Как вернуть значение по умолчанию для атрибута?
У меня есть объект "myobject
", который может вернуться None
. Если он возвращает None
, он не вернет атрибут "id
":
a = myobject.id
Итак, когда myobject равен None
, строя выше приводит к атрибуту AttributeError:
AttributeError: 'NoneType' object has no attribute 'id'
Если myobject
- None, то я хочу, чтобы "a
" был равен None. Как избежать этого исключения в одном выражении строки, например:
a= default(myobject.id, None)
Ответы
Ответ 1
Вы должны использовать обертку getattr
вместо прямого извлечения значения id
.
a = getattr(myobject, 'id', None)
Это похоже на высказывание "Я хотел бы получить атрибут id
из объекта myobject
, но если в объекте myobject
нет атрибута id
, тогда верните None
". Но он делает это эффективно.
Некоторые объекты также поддерживают следующий вид доступа getattr
:
a = myobject.getattr('id', None)
В соответствии с запросом OP 'deep getattr':
def deepgetattr(obj, attr):
"""Recurses through an attribute chain to get the ultimate value."""
return reduce(getattr, attr.split('.'), obj)
# usage:
print deepgetattr(universe, 'galaxy.solarsystem.planet.name')
Простое объяснение:
Reduce - это как рекурсивная функция на месте. В этом случае он начинается с obj
(юниверса), а затем рекурсивно становится более глубоким для каждого атрибута, к которому вы пытаетесь получить доступ, используя getattr
, поэтому в вашем вопросе он будет выглядеть следующим образом:
a = getattr(getattr(myobject, 'id', None), 'number', None)
Ответ 2
Самый простой способ - использовать тернарный оператор:
a = myobject.id if myobject is not None else None
Тернарный оператор возвращает первое выражение, если среднее значение истинно, иначе оно возвращает последнее выражение.
Обратите внимание, что вы также можете сделать это по-другому, используя исключения:
try:
a = myobject.id
except AttributeError:
a = None
Это соответствует идеалу Питонов, что легче попросить прощения, чем разрешение - что лучше всего будет зависеть от ситуации.
Ответ 3
в моем классе объектов вы можете поместить переопределение
class Foo(object):
def __getattribute__(self, name):
if not name in self;
return None;
else:
# Default behaviour
return object.__getattribute__(self, name)
Ответ 4
Справка по встроенной функции getattr в встроенных модулях:
getattr(...)
getattr(object, name[, default]) -> value
Получить именованный атрибут объекта; getattr (x, 'y') эквивалентно x.y. Когда задан аргумент по умолчанию, он возвращается, когда атрибут не существовать; без него в этом случае возникает исключение.
Следующее должно работать:
a = getattr(myobject, 'id', None)
Ответ 5
try:
a = myobject.id
except AttributeError:
a = None
Будет также работать и яснее, IMO
Ответ 6
a=myobect.id if myobject else None
Ответ 7
Если вы хотите решить проблему в определении класса myobject
(например, в Black Diamond answer), вы можете просто определить __getattr__
для возврата None
:
class Myobject:
def __getattr__(self, name):
return None
Это работает, потому что __getattr__
вызывается только при попытке получить доступ к атрибуту, который не существует, тогда как __getattribute__
всегда вызывается первым независимо от имени атрибута. (См. Также этот SO сообщение.)
Чтобы опробовать:
myobject = Myobject()
print myobject.id
myobject.id = 7
print myobject.id