506 votes

Différence entre __getattr__ et __getattribute__

J'essaie de comprendre quand utiliser __getattr__ ou __getattribute__ . Le site documentation mentionne __getattribute__ s'applique aux classes de type nouveau. Qu'est-ce qu'une classe de type nouveau ?

2 votes

12 votes

@Trilarion pourtant cette question mentionne une réponse d'ici...

4voto

Dorcioman Points 107
  • obtenir l'attribut : Est utilisé pour récupérer un attribut d'une instance. Il capture chaque tentative d'accès à un attribut d'instance en utilisant la notation point ou la fonction intégrée getattr().
  • getattr : Est exécuté comme dernière ressource lorsque l'attribut n'est pas trouvé dans un objet. Vous pouvez choisir de retourner une valeur par défaut ou de lever AttributeError.

Pour en revenir à la __getattribut__ si l'implémentation par défaut n'a pas été remplacée, les contrôles suivants sont effectués lors de l'exécution de la méthode :

  • Vérifier s'il existe un descripteur portant le même nom (nom de l'attribut) défini dans une classe quelconque de la chaîne MRO (résolution d'objet de méthode).
  • Ensuite, on regarde dans l'espace de nom de l'instance
  • Ensuite, on regarde dans l'espace de nom de la classe
  • Puis dans l'espace de noms de chaque base et ainsi de suite.
  • Enfin, si elle n'est pas trouvée, l'implémentation par défaut appelle la méthode de repli (fallback) getattr () de l'instance et elle lève une exception AttributeError comme implémentation par défaut.

Il s'agit de l'actuel mise en œuvre de la méthode object.__getattribute__ :

. c:fonction: : PyObject* PyObject_GenericGetAttr(PyObject *o, PyObject *name) Fonction générique de récupération d'attribut qui est destinée à être placée dans le slot tp_getattro d'un objet de type. être placée dans le slot tp_getattro d'un objet de type. Elle recherche un descripteur dans le dictionnaire des classes dans le MRO de l'objet ainsi que ainsi qu'un attribut dans le :attr:~object de l'objet. dict (si présents). Comme indiqué dans :ref:descriptors, les descripteurs de données ont la préférence sur les attributs d'instance, tandis que les descripteurs non-données ne le font pas. Dans le cas contraire, une erreur :exc:AttributeError est générée.

3voto

soporific312 Points 117

En lisant le PCB de Beazley & Jones, je suis tombé sur un cas d'utilisation explicite et pratique de l'outil de gestion de l'information. __getattr__ qui aide à répondre à la partie "quand" de la question de l'OP. Dans le livre :

" Le __getattr__() est en quelque sorte un fourre-tout pour la recherche d'attributs. C'est une méthode qui est appelée si le code tente d'accéder à un attribut qui n'existe pas." Nous le savons d'après les réponses ci-dessus, mais dans la recette PCB 8.15, cette fonctionnalité est utilisée pour implémenter la méthode modèle de conception de délégation . Si l'objet A possède un attribut objet B qui implémente de nombreuses méthodes que l'objet A veut déléguer, plutôt que de redéfinir toutes les méthodes de l'objet B dans l'objet A juste pour appeler les méthodes de l'objet B, définissez une méthode __getattr__() comme suit :

def __getattr__(self, name):
    return getattr(self._b, name)

où _b est le nom de l'attribut de l'objet A qui est un objet B. Lorsqu'une méthode définie sur l'objet B est appelée sur l'objet A, la fonction __getattr__ sera invoquée à la fin de la chaîne de recherche. Cela rendrait également le code plus propre, puisque vous n'avez pas une liste de méthodes définies juste pour déléguer à un autre objet.

3voto

youkaichao Points 1158

Je trouve que personne ne mentionne cette différence :

__getattribute__ a une implémentation par défaut, mais __getattr__ ne le fait pas.

class A:
    pass
a = A()
a.__getattr__ # error
a.__getattribute__ # return a method-wrapper

Cela a une signification claire : puisque __getattribute__ a une implémentation par défaut, tandis que __getattr__ non, il est clair que python encourage les utilisateurs à implémenter __getattr__ .

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X