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)
28
demandé sur Martin Thoma 2013-02-17 20:48:25

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)

79
répondu Inbar Rose 2015-02-25 16:23:32

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.

10
répondu Gareth Latty 2013-02-17 16:49:44

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)
6
répondu Black Diamond 2013-02-17 16:57:12

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)
2
répondu shantanoo 2013-02-17 16:59:57

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
1
répondu matec 2017-06-30 18:45:35
try:
    a = myobject.id
except AttributeError:
    a = None

fonctionnera aussi et est plus clair, IMO

0
répondu hd1 2013-02-17 16:51:17
a=myobect.id if myobject else None
0
répondu Anil 2013-02-17 16:53:54