2014-02-15 4 views
3

Как вы можете это объяснить:Python не может поймать переопределены NameError

Этот код должен переопределить NameError, а затем поймать его.

OldNameError = NameError 
class NameError(OldNameError): 
    pass 

try: 
    ccc 
except NameError as e: 
    print "hi" 

Не печатает "привет". Вместо этого вывод:

Traceback (most recent call last): 
    File "try.py", line 6, in <module> 
    ccc 
NameError: name 'ccc' is not defined 

Но этот код:

OldNameError = NameError 
class NameError(OldNameError): 
    pass 

try: 
    raise NameError("oo") 
except NameError: 
    print "hi" 

дает выход я хотел:

hi 

Что такое объяснение?

Спасибо!

ответ

3

Когда вы пишете except NameError, вы говорите, что хотите поймать исключения того типа, которого NameError ссылается на момент, когда вы делаете ловушку. Поскольку вы изменили то, что NameError, вы пытаетесь поймать свой новый класс. Но исключение, которое возникает, является «реальным» NameError, а не вашим чрезмерным.

Вы можете увидеть это, если вы измените условия, за исключением пункта:

try: 
    ccc 
except Exception as e: 
    print isinstance(e, NameError) 
    print isinstance(e, OldNameError) 

Выход:

False 
True 

. , , что повышенное исключение - это OldNameError, а не новый NameError.

Вы не можете изменить, какое исключение вызвано из-за неопределенного имени. Вы можете создать что-то под названием NameError, но оно никогда не будет использоваться, если вы не используете его явно (как это было в вашем втором примере).

+0

Почему я не могу изменить то, что поднято? Он должен быть определен где-то, и я должен его переопределить, не так ли? –

+0

@EllaShar: Он не определен в коде Python. Чтобы изменить его, вам нужно будет изменить сам Python iterpreter. Зачем вам это делать? – BrenBarn

+0

Спасибо. Но что происходит, когда я пишу 'ccc', и это не определено? Как python «знает», какое исключение поднять? –

Смежные вопросы