2016-02-23 4 views

ответ

11

Реализация python2 из hasattr довольно наивный, он просто пытается получить доступ к этому атрибуту и ​​посмотреть, поднимает ли это исключение или нет.

К сожалению, это означает, что любые необработанные исключения внутри свойств будут проглатываться, а ошибки в этом коде могут быть потеряны. Чтобы добавить оскорбление к травме, когда hasattr съедает исключение, оно также вернет неверный ответ (здесь есть атрибут a.foo,, поэтому результат должен был вернуть True, если таковой имеется).

В python3.2 +, поведение было исправлено:

hasattr(object, name)

Аргументов является объектом и строка. Результат: True, если строка является именем одного из атрибутов объекта, False, если нет. (Это осуществляется путем вызова getattr(object, name) и, видя, поднимает ли оно AttributeError или нет.)

Исправление here, но, к сожалению, это изменение не портировать.

Если поведение python2 вызывает у вас проблемы, учтите, что не используйте hasattr; вместо этого вы можете использовать try/except около getattr, перехватывая только исключение AttributeError и позволяя любым другим поднимать необработанные.

+4

Цитата из документов Python, несмотря на то, что поведение hasattr по-прежнему может считаться странным. Верно, что произвольные исключения внутри свойства больше не приводят к тому, что атрибут считается отсутствующим (но скорее возникают на лице вызывающего), но если атрибут 'AttributeError' происходит откуда-то внутри свойства, результат' hasattr' будет по-прежнему быть «ложным». Это может быть не преднамеренным. (Или это может, поэтому свойство может определить себя, хочет ли он быть «там».) В любом случае выполнение свойства звучит неправильно для меня в первую очередь, учитывая побочные эффекты и т. Д. –

+0

На самом деле нет простого способа чтобы определить, был ли атрибут «AttributeError» поднят самим механизмом получения атрибутов или кодом в свойстве. – kindall

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