Как узнать, имеет ли объект атрибут в 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