Реализация python2 из hasattr довольно наивный, он просто пытается получить доступ к этому атрибуту и посмотреть, поднимает ли это исключение или нет.
К сожалению, это означает, что любые необработанные исключения внутри свойств будут проглатываться, а ошибки в этом коде могут быть потеряны. Чтобы добавить оскорбление к травме, когда hasattr съедает исключение, оно также вернет неверный ответ (здесь есть атрибут a.foo
,, поэтому результат должен был вернуть True
, если таковой имеется).
В python3.2 +, поведение было исправлено:
hasattr(object, name)
Аргументов является объектом и строка. Результат: True
, если строка является именем одного из атрибутов объекта, False
, если нет. (Это осуществляется путем вызова getattr(object, name)
и, видя, поднимает ли оно AttributeError
или нет.)
Исправление here, но, к сожалению, это изменение не портировать.
Если поведение python2 вызывает у вас проблемы, учтите, что не используйте hasattr
; вместо этого вы можете использовать try/except около getattr
, перехватывая только исключение AttributeError
и позволяя любым другим поднимать необработанные.
Цитата из документов Python, несмотря на то, что поведение hasattr по-прежнему может считаться странным. Верно, что произвольные исключения внутри свойства больше не приводят к тому, что атрибут считается отсутствующим (но скорее возникают на лице вызывающего), но если атрибут 'AttributeError' происходит откуда-то внутри свойства, результат' hasattr' будет по-прежнему быть «ложным». Это может быть не преднамеренным. (Или это может, поэтому свойство может определить себя, хочет ли он быть «там».) В любом случае выполнение свойства звучит неправильно для меня в первую очередь, учитывая побочные эффекты и т. Д. –
На самом деле нет простого способа чтобы определить, был ли атрибут «AttributeError» поднят самим механизмом получения атрибутов или кодом в свойстве. – kindall