Подтвердить что ты не робот

Как вернуть значение по умолчанию для атрибута?

У меня есть объект "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)
4b9b3361

Ответ 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