Python >> Tutoriel Python >  >> Python

Méthode magique Python __getattribute__()

La méthode magique de Python __getattribute__() implémente le getattr() intégré fonction qui renvoie la valeur associée à un nom d'attribut donné. Si le __getattribute__() l'erreur se traduit par un AttributeError en raison d'un attribut inexistant, Python appellera le __getattr__() fonction de résolution.

Ainsi, le __getattribute__() la méthode a priorité sur le __getattr__() méthode.

Nous appelons cela une "méthode Dunder" pour "D ouble Sous Méthode de score" (également appelée "méthode magique" ). Pour obtenir une liste de toutes les méthodes de dunder avec des explications, consultez notre article sur la feuille de triche de dunder sur ce blog.

Syntaxe et exemple minimal

object.__getattribute__(self, attr_name)

Examinons un exemple où vous remplacez le __getattribute__ méthode magique d'une classe personnalisée Person pour imprimer simplement la chaîne 'hello world' lors de l'appel du getattr() fonction intégrée.

class Person:
    def __getattribute__(self, attr_name):
        print('hello world')
    

alice = Person()
getattr(alice, 'age')
# hello world

__getattribute__ contre __getattr__

Le __getattribute__ la méthode est similaire à __getattr__ . Quelle est la différence ?

Supposons qu'un utilisateur souhaite accéder à un attribut à partir d'un objet donné comme suit :

my_obj.my_attr
  • my_obj.__getattribute__(my_attr) est appelé en premier. S'il donne un AttributeError , Python le remettra à :
  • my_obj.__getattr__(my_attr) qui est appelé deuxième.

Vous pouvez voir que la première a priorité sur la seconde dans l'extrait de code suivant qui définit les deux méthodes, mais __getattribute__() est pris car il ne génère pas d'erreur.

class Person:
    def __getattribute__(self, attr_name):
        print('hello world')

    def __getattr__(self, attr_name):
        print('hello universe')
    

alice = Person()
getattr(alice, 'age')
# hello world

Voici ce qui se serait passé dans le même scénario lors de la levée d'un AttributeError en __getattribute__ :

class Person:
    def __getattribute__(self, attr_name):
        raise AttributeError

    def __getattr__(self, attr_name):
        print('hello universe')
    

alice = Person()
getattr(alice, 'age')
# hello universe

Python ne mentionne même pas l'erreur mais passe le flux d'exécution au __getattr__() méthode.

Getattr() en arrière-plan

getattr(object, string) intégré de Python la fonction retourne la valeur du object 's attribut avec le nom string .

S'il n'existe pas, il renvoie la valeur fournie sous la forme d'un troisième default facultatif dispute.

Si cela n'existe pas non plus, cela lève un AttributeError .

Un exemple est getattr(porsche, 'speed') qui équivaut à porsche.speed .

# Define class with one attribute
class Car:
    def __init__(self, brand, speed):
        self.brand = brand
        self.speed = speed


# Create object
porsche = Car('porsche', 100)
tesla = Car('tesla', 110)

# Two alternatives to get instance attributes:
print(getattr(porsche, 'brand') + " " + str(getattr(porsche, 'speed')))
print(tesla.brand + " " + str(tesla.speed))


# Get an attribute that doesn't exist with default argument:
print(getattr(porsche, 'color', 'red'))

Sortie :

porsche 100
tesla 110
red

Autres lectures :

  • Python __delattr__() méthode magique
  • Python setattr() fonction intégrée
  • Python getattr() fonction intégrée
  • Python __getattr__() contre __getattribute__()
  • https://docs.python.org/3/reference/datamodel.html