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

Ответы

Ответ 1

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

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

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

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

Ответ 2

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

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

то есть:

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

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

if hasattr(a, 'property'):
    doStuff(a.property)
else:
    otherStuff()

Ответ 3

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

getattr(a, 'property', 'default value')

Ответ 4

Я думаю, что вы ищете hasattr. Тем не менее, я бы рекомендовал что-то подобное, если вы хотите обнаружить свойства python -

try:
    getattr(someObject, 'someProperty')         
except AttributeError:
    print "Doesn't exist"
else
    print "Exists"

Недостатком здесь является то, что ошибки атрибутов в коде свойств __get__ также попадают.

В противном случае do -

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

Ответ 5

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

a = SomeClass()
try:
    return a.fake_prop
except AttributeError:
    return default_value

Ответ 6

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

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

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

Возможно, этот подход лучше:

try:
    val = a.property
except AttributeError:
    otherStuff()
else:
    doStuff(val)

Ответ 7

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

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

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

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

Ответ 8

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

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

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

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

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

Ответ 9

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

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

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

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

Ответ 10

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

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

Ответ 11

Вы можете проверить, содержит ли 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 в объекте.

Ответ 12

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

Ответ 13

Еще один возможный вариант, но это зависит от того, под чем вы подразумеваете:

undefined = object()

class Widget:

    def __init__(self):
        self.bar = 1

    def zoom(self):
        print("zoom!")

a = Widget()

bar = getattr(a, "bar", undefined)
if bar is not undefined:
    print("bar:%s" % (bar))

foo = getattr(a, "foo", undefined)
if foo is not undefined:
    print("foo:%s" % (foo))

zoom = getattr(a, "zoom", undefined)
if zoom is not undefined:
    zoom()

выход:

bar:1
zoom!

Это позволяет вам даже проверять наличие ненулевых атрибутов.

Но! Будьте очень осторожны, вы не можете случайно создать и сравнить undefined несколько мест, потому что is никогда не сработает в этом случае.