web-dev-qa-db-fra.com

Comment puis-je retourner une valeur par défaut pour un attribut?

J'ai un objet myobject, qui pourrait retourner None. S'il renvoie None, il ne renverra pas d'attribut id:

a = myobject.id

Ainsi, lorsque mon objet est None, le stament ci-dessus se traduit par un AttributeError:

AttributeError: 'NoneType' object has no attribute 'id'

Si myobject est None, alors je veux que a soit égal à None. Comment puis-je éviter cette exception dans une déclaration d'une ligne, telle que:

a = default(myobject.id, None)
33
alwbtc

Vous devez utiliser le wrapper getattr au lieu de récupérer directement la valeur de id.

a = getattr(myobject, 'id', None)

C'est comme dire "Je voudrais récupérer l'attribut id de l'objet myobject, mais s'il n'y a pas d'attribut id à l'intérieur de l'objet myobject, puis renvoyez None à la place. " Mais il le fait efficacement.

Certains objets prennent également en charge la forme suivante d'accès getattr:

a = myobject.getattr('id', None)

Selon la demande 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')

Explication simple:

Réduire est comme une fonction récursive sur place. Dans ce cas, cela commence par obj (univers), puis approfondit récursivement pour chaque attribut auquel vous essayez d'accéder en utilisant getattr, donc dans votre question, ce serait comme ceci:

a = getattr(getattr(myobject, 'id', None), 'number', None)

86
Inbar Rose

La manière la plus simple est d'utiliser l'opérateur ternaire:

a = myobject.id if myobject is not None else None

L'opérateur ternaire renvoie la première expression si la valeur du milieu est vraie, sinon il renvoie la dernière expression.

Notez que vous pouvez également le faire d'une autre manière, en utilisant des exceptions:

try:
    a = myobject.id
except AttributeError:
    a = None

Cela correspond à l'idéal Pythonic selon lequel il est plus facile de demander pardon que permission - ce qui dépend le mieux de la situation.

10
Gareth Latty

dans ma classe d'objets, vous pouvez mettre la priorité

class Foo(object):
   def __getattribute__(self, name):
      if not name in self;
        return None;
      else:
        # Default behaviour
        return object.__getattribute__(self, name)
6
Black Diamond

Aide sur la fonction intégrée getattr dans les modules intégrés:

getattr(...)
    getattr(object, name[, default]) -> value

Obtenez un attribut nommé d'un objet; getattr (x, 'y') est équivalent à x.y. Lorsqu'un argument par défaut est donné, il est renvoyé lorsque l'attribut n'existe pas; sans elle, une exception est soulevée dans ce cas.

Ce qui suit devrait fonctionner:

a = getattr(myobject, 'id', None)
2
shantanoo

Si vous voulez résoudre le problème dans la définition de la classe de myobject (comme dans réponse de Black Diamond ), vous pouvez simplement définir __getattr__ pour retourner None:

class Myobject:
    def __getattr__(self, name):
        return None

Cela fonctionne parce que __getattr__ n'est appelé que lorsque vous tentez d'accéder à un attribut qui n'existe pas, tandis que __getattribute__ est toujours appelé en premier, quel que soit le nom de l'attribut. (Voir aussi this SO post .)

Essayer:

myobject = Myobject()
print myobject.id 
myobject.id = 7
print myobject.id
2
matec
a=myobect.id if myobject else None
0
Anil
try:
    a = myobject.id
except AttributeError:
    a = None

Fonctionnera également et est plus clair, OMI

0
hd1