Как узнать, есть ли у объекта атрибут в Python
-
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 )
Это вернет список всех доступных функций и атрибутов объекта.