Comment retourner une valeur par défaut pour un attribut? [dupliquer]
cette question a déjà une réponse ici:
j'ai un objet " myobject
", ce qui pourrait revenir None
. S'il retourne None
, il ne retournera pas un attribut " id
":
a = myobject.id
Ainsi, lorsque myobject est None
, l'énoncé ci-dessus résulte en un AttributeError:
AttributeError: 'NoneType' object has no attribute 'id'
si myobject
n'est rien, alors je veux que a
" soit égal à aucun. Comment puis-je éviter cette exception dans un énoncé d'une ligne, tel que:
a= default(myobject.id, None)
7 réponses
vous devez utiliser le 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 si il n'y a pas d'attribut id
à l'intérieur de l'objet myobject
, puis de retour None
à la place."Mais elle le fait de manière efficace.
Certains objets supportent également le forme suivante de getattr
accès:
a = myobject.getattr('id', None)
conformément à l'OP demande, profonde "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 , c'est comme une fonction récursive. Ce qu'il fait dans ce cas est de commencer par le obj
(univers) et puis obtenir récursivement plus profond pour chaque attribut que vous essayez d'accéder en utilisant getattr
, donc dans votre question il serait comme ceci:
a = getattr(getattr(myobject, 'id', None), 'number', None)
la façon 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 moyenne 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 pythonique qu'il est plus facile de demander le pardon que la permission - ce qui est mieux dépendra de la situation.
dans ma classe d'objet, vous pouvez mettre override
class Foo(object):
def __getattribute__(self, name):
if not name in self;
return None;
else:
# Default behaviour
return object.__getattribute__(self, name)
aide sur la fonction intégrée getattr dans les modules builtins:
getattr(...) getattr(object, name[, default]) -> value
obtient un attribut nommé d'un objet; getattr(x, 'y') est équivalent à X. Y. Quand un argument par défaut est donné, il est retourné quand l'attribut ne existent; sans elle, une exception est levée dans ce cas.
suivant devrait fonctionner:
a = getattr(myobject, 'id', None)
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é qu'en essayant d'accéder à un attribut qui n'existe pas, alors que __getattribute__
est toujours appelé en premier, quel que soit le nom de l'attribut. (Voir aussi ce tant de poster .)
à essayer:
myobject = Myobject()
print myobject.id
myobject.id = 7
print myobject.id
try:
a = myobject.id
except AttributeError:
a = None
fonctionnera aussi et est plus clair, IMO