Как узнать, есть ли у объекта атрибут в Python - PullRequest
1369 голосов
/ 04 марта 2009

Есть ли в 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 перед его использованием?

Ответы [ 12 ]

1934 голосов
/ 04 марта 2009

Попробуйте hasattr():

if hasattr(a, 'property'):
    a.property

РЕДАКТИРОВАТЬ: См. ответ zweiterlinde ниже, который предлагает хороший совет о том, как просить прощения! Очень питонический подход!

Общая практика в python заключается в том, что, если свойство, скорее всего, присутствует там большую часть времени, просто вызовите его и либо разрешите распространению исключения, либо перехватите его с помощью блока try / исключением. Это, вероятно, будет быстрее, чем hasattr. Если это свойство, скорее всего, отсутствует в большинстве случаев, или вы не уверены, использование hasattr, вероятно, будет быстрее, чем повторное попадание в блок исключения.

551 голосов
/ 04 марта 2009

Как ответил Джаррет Харди , hasattr сделает свое дело. Я хотел бы добавить, однако, что многие в сообществе Python рекомендуют стратегию «проще просить прощения, чем разрешения» (EAFP), а не «смотреть перед прыжком» (LBYL). Смотрите эти ссылки:

EAFP против LBYL (пока Re: немного разочарован)
EAFP vs. LBYL @Code Как у Pythonista: Идиоматический Python

т

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

... предпочтительнее:

if hasattr(a, 'property'):
    doStuff(a.property)
else:
    otherStuff()
423 голосов
/ 04 марта 2009

Вы можете использовать hasattr() или перехватить AttributeError, но если вам действительно нужно значение атрибута со значением по умолчанию, если его там нет, лучшим вариантом будет просто использовать getattr():

getattr(a, 'property', 'default value')
36 голосов
/ 04 марта 2009

Я думаю, что вы ищете 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

Документы: http://docs.python.org/library/functions.html
Внимание:
Причиной моей рекомендации является то, что hasattr не определяет свойства.
Ссылка: http://mail.python.org/pipermail/python-dev/2005-December/058498.html

28 голосов
/ 04 марта 2009

Согласно pydoc, hasattr (obj, prop) просто вызывает getattr (obj, prop) и перехватывает исключения. Таким образом, столь же правильно обернуть доступ к атрибуту оператором try и перехватить AttributeError, как и использовать hasattr () заранее.

a = SomeClass()
try:
    return a.fake_prop
except AttributeError:
    return default_value
22 голосов
/ 26 августа 2016

Я хотел бы предложить избежать этого:

try:
    doStuff(a.property)
except AttributeError:
    otherStuff()

Пользователь @jpalecek упомянул это: если AttributeError находится внутри doStuff(), вы потерялись.

Может быть, этот подход лучше:

try:
    val = a.property
except AttributeError:
    otherStuff()
else:
    doStuff(val)
12 голосов
/ 04 марта 2009

В зависимости от ситуации вы можете проверить с помощью isinstance, какой у вас объект, а затем использовать соответствующие атрибуты. С введением абстрактных базовых классов в Python 2.6 / 3.0 этот подход также стал намного более мощным (в основном ABC допускают более изощренный способ утки).

Одна ситуация, в которой это было бы полезно, была бы, если бы два разных объекта имели атрибут с одинаковым именем, но с разным значением. Использование только hasattr может привести к странным ошибкам.

Один хороший пример - это различие между итераторами и итераторами (см. этот вопрос). Методы __iter__ в итераторе и итерации имеют одно и то же имя, но семантически совершенно разные! Так что hasattr бесполезен, но isinstance вместе с ABC обеспечивает чистое решение.

Однако я согласен с тем, что в большинстве ситуаций подход hasattr (описанный в других ответах) является наиболее подходящим решением.

10 голосов
/ 30 декабря 2016

Надеюсь, вы ожидаете hasattr (), но старайтесь избегать hasattr () и, пожалуйста, предпочитайте getattr (). getattr () быстрее, чем hasattr ()

с использованием hasattr ():

 if hasattr(a, 'property'):
     print a.property

то же самое, здесь я использую getattr для получения свойства, если нет свойства, возвращаемого нет

   property = getattr(a,"property",None)
    if property:
        print property
9 голосов
/ 22 июня 2017

РЕДАКТИРОВАТЬ : этот подход имеет серьезные ограничения. Он должен работать, если объект является повторяемым . Пожалуйста, проверьте комментарии ниже.

Если вы используете Python 3.6 или выше, как я, есть удобная альтернатива, чтобы проверить, имеет ли объект определенный атрибут:

if 'attr1' in obj1:
    print("attr1 = {}".format(obj1["attr1"]))

Однако я не уверен, какой сейчас самый лучший подход. используя hasattr(), используя getattr() или in. Комментарии приветствуются.

0 голосов
/ 25 мая 2019

Вот очень интуитивный подход:

if 'property' in dir(a):
    a.property
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...