Как узнать, имеет ли объект атрибут в Python
есть ли способ в Python определить, имеет ли объект какой-либо атрибут? Например:
>>> a = SomeClass()
>>> a.someProperty = value
>>> a.property
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: SomeClass instance has no attribute 'property'
как вы можете сказать, если a
атрибут property
перед его использованием?
9 ответов
попробовать hasattr()
:
if hasattr(a, 'property'):
a.property
EDIT: см. zweiterlinde это!--6--> ниже, кто предлагает хороший совет о просить прощения! Очень подходящие для Python подход!
общая практика в python заключается в том, что, если свойство, вероятно, будет там большую часть времени, просто вызовите его и либо дайте исключению распространяться, либо поймайте его с помощью блока try/except. Это, вероятно, будет быстрее, чем hasattr
. Если свойство, вероятно, не будет там большая часть время, или вы не уверены, используя hasattr
вероятно, будет быстрее, чем многократное попадание в блок исключений.
As Джаррет Харди ответил:hasattr
будет делать трюк. Однако я хотел бы добавить, что многие в сообществе Python рекомендуют стратегию "легче просить прощения, чем разрешения" (EAFP), а не "смотреть, прежде чем прыгать" (LBYL). См. следующие ссылки:
EAFP vs LBYL (был Re: немного разочарован до сих пор)
EAFP против LBYL @Code как Pythonista: идиоматический Питон
ie:
try:
doStuff(a.property)
except AttributeError:
otherStuff()
... предпочтительно:
if hasattr(a, 'property'):
doStuff(a.property)
else:
otherStuff()
можно использовать hasattr()
или поймать AttributeError
, но если вы действительно просто хотите значение атрибута по умолчанию, если его нет, лучший вариант - просто использовать getattr()
:
getattr(a, 'property', 'default value')
Я думаю, что вы ищете hasattr. Тем не менее, я бы рекомендовал что-то вроде этого, если вы хотите обнаружить свойства python-
try:
getattr(someObject, 'someProperty')
except AttributeError:
print "Doesn't exist"
else
print "Exists"
недостатком здесь является то, что ошибки атрибутов в свойствах __get__
код тоже ловят.
в противном случае, делать-
if hasattr(someObject, 'someProp'):
#Access someProp/ set someProp
pass
Docs:http://docs.python.org/library/functions.html
Warning:
Причина моей рекомендации это то, что hasattr не обнаруживает свойства.
Ссылка:http://mail.python.org/pipermail/python-dev/2005-December/058498.html
согласно pydoc, hasattr(obj, prop) просто вызывает getattr (obj, prop) и ловит исключения. Таким образом, точно так же допустимо обернуть доступ к атрибуту с помощью оператора try и catch AttributeError, как и использовать hasattr() заранее.
a = SomeClass()
try:
return a.fake_prop
except AttributeError:
return default_value
Я хотел бы предложить избежать этого:
try:
doStuff(a.property)
except AttributeError:
otherStuff()
пользователь @jpalecek упомянул об этом: если AttributeError
происходит внутри doStuff()
, вы потеряли.
может быть, этот подход лучше:
try:
val = a.property
except AttributeError:
otherStuff()
else:
doStuff(val)
в зависимости от ситуации вы можете проверить с isinstance
какой у вас объект, а затем используйте соответствующие атрибуты. С введением абстрактные базовые классы в Python 2.6 / 3.0 Этот подход также стал гораздо более мощным (в основном ABCs позволяют более сложный способ ввода утки).
одна ситуация была бы полезна, если бы два разных объекта имели атрибут с тем же именем, но с другим значением. Используя только hasattr
затем может привести к странным ошибкам.
одним из хороших примеров является различие между итераторами и итерациями (см. этой вопрос). The __iter__
методы в итераторе и iterable имеют одно и то же имя, но семантически совершенно разные! Так что hasattr
бесполезно, но isinstance
вместе с ABC обеспечивает чистое решение.
тем не менее, я согласен, что в большинстве ситуаций hasattr
подход (описано в других ответах) является наиболее подходящим решение.
редактировать:такой подход имеет серьезные ограничения. Он должен работать, если объект является типа Iterable один. Пожалуйста, проверьте комментарии ниже.
если вы используете Python 3.6 или выше, как я есть удобная альтернатива, чтобы проверить, имеет ли объект определенный атрибут:
if 'attr1' in obj1:
print("attr1 = {}".format(obj1["attr1"]))
тем не менее, я не уверен, что это лучший подход прямо сейчас. используя hasattr()
, используя getattr()
или через in
. Комментарии добро пожаловать.
надеюсь, вы ожидаете hasattr (), но старайтесь избегать hasattr () и, пожалуйста, предпочитайте getattr (). getattr () быстрее, чем hasattr ()
использовать hasattr():
if hasattr(a, 'property'):
print a.property
то же самое здесь я использую getattr для получения свойства, если нет свойства, оно не возвращает none
property = getattr(a,"property",None)
if property:
print property