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