Как узнать, есть ли у объекта атрибут в Python

StackOverflow https://stackoverflow.com/questions/610883

  •  03-07-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

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

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

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

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

Другие советы

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

EAFP против LBYL (был Повторно:Пока что немного разочарован)
EAFP противLBYL @Кодируй Как Питонист:Идиоматический Python

т. е.:

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

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

Согласно pydoc, hasattr (obj, prop) просто вызывает getattr (obj, prop) и перехватывает исключения. Таким образом, столь же правильно обернуть доступ к атрибуту оператором try и перехватить 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 этот подход получил также становятся намного более мощными (в основном ABC позволяют более утонченный способ печати утки).

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

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

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

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

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

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

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

   property = getattr(a,"property",None)
    if property:
        print property

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

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

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

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

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

if 'property' in dir(a):
    a.property

Вы можете проверить, содержит ли object атрибут, используя встроенный метод hasattr .

Например, если ваш объект a и вы хотите проверить наличие атрибута stuff

>>> class a:
...     stuff = "something"
... 
>>> hasattr(a,'stuff')
True
>>> hasattr(a,'other_stuff')
False

Самой сигнатурой метода является hasattr (object, name) - > bool , что означает, что если object имеет атрибут , который передается второму аргументу в hasattr , то это дает логическое значение True или False в зависимости от наличия атрибута name в объекте.

Это очень просто, просто используйте dir ( object )
Это вернет список всех доступных функций и атрибутов объекта.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top