2016-06-21 5 views
2

Python 2.7.10, похоже, преобразует мою строку в кортеж при броске в исключение. Вот мой пример:Строка Python в исключении, преобразованная в кортеж

class MyError(RuntimeError): 
    def __init__(self, arg): 
     self.args = arg 

def raiseMyError(): 
    errorCode = 29 
    errorText = 'Port not ready yet' 
    exitCodeMessage = 'ERROR {0}: {1}'.format(errorCode, errorText) 
    # print exitCodeMessage --> print out here and it's a string 
    raise MyError(str(exitCodeMessage)) 

try: 
    raiseMyError() 

except MyError as e: 
    print e.args 

создать строку, содержащую код и описание ошибки и использовать это, чтобы построить универсальный встроенный класс исключений. Когда я распечатать exitCodeMessage переменную перед создается исключение я получаю то, что я ожидал:

ERROR 29: Port not ready yet 

Однако след из обработчика исключений дает мне следующее:

('E', 'R', 'R', 'O', 'R', ' ', '2', '9', ':', ' ', 'P', 'o', 'r', 't', ' ', 'n', 'o', 't', 
' ', 'r', 'e', 'a', 'd', 'y', ' ', 'y', 'e', 't') 

Может кто-нибудь расскажи мне, что здесь происходит и что я могу с этим поделать?

+0

класс 'MyError (RuntimeError): pass' –

ответ

2

На самом деле вам не нужно переопределить метод __init__ вообще, это достаточно достаточно, чтобы:

class MyError(RuntimeError): 
    pass 

Что касается поведения - docs состояние, которое args является:

The tuple of arguments given to the exception constructor.

При наследовании от Exception класс или любой из его детей печать e.args будет просто напечатать tuple(e.args), так как args свойство определено в таких в классе Exception (см. @ advance512 ответ).

Если вы не наследуют от Exception:

class MyError: 

    def __init__(self, arg): 
     self.args = arg 

вы не наследуют «магию» за args, таким образом, вызывая e.args будет работать, как ожидалось.

Вы могли бы также написать, как это (обратите внимание self.arg вместо self.args):

class MyError(RuntimeError): 

    def __init__(self, arg): 
     self.arg = arg 

и призывающих e.arg также будет работать, как ожидалось.

+0

Это правда. Тем не менее, мне интересно понять, почему в этом случае он делает это преобразование. Я также заметил, что если я не наследую от «RuntimeError», но сохраняю остальную часть кода как есть, она работает нормально, поэтому, вероятно, в RuntimeError есть что-то, что вызывает это. –

+0

Поведение точно такое же, наследуется ли вы от «RuntimeError» или «Exception». – matino

+0

Я должен был уточнить, что я меняю код так, чтобы 'MyError' не наследовал ни от чего (т. Е.' Class MyError: '), и он работал так, как я ожидал. Как вы говорите, мой '__init__' здесь не нужен. –

2

Это потому, что args является свойством, которое определено в классе BaseException.

ЗАКАНЧИВАТЬ exceptions.py:70:

args = property(lambda self: tuple())

Попробуйте это:

class MyError(RuntimeError): 
    def __init__(self, errorString): 
     self._errorString = errorString 

def raiseMyError(): 
    errorCode = 29 
    errorText = 'Port not ready yet' 
    exitCodeMessage = 'ERROR %s: %s' % (errorCode, errorText) 
    # print exitCodeMessage --> print out here and it's a string 
    raise MyError(exitCodeMessage) 

try: 
    raiseMyError() 

except MyError as e: 
    print e._errorString 
    print e.args 

выход:

ERROR 29: Port not ready yet 
() 
Смежные вопросы