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)
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)
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.
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)
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)
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
a=myobect.id if myobject else None
try:
a = myobject.id
except AttributeError:
a = None
Fonctionnera également et est plus clair, OMI