Comment jongler avec les recherches python: make.up.a.dot.separated.name.and.use.it.until.destroyed = 777

StackOverflow https://stackoverflow.com/questions/1602745

  •  05-07-2019
  •  | 
  •  

Question

Je suis un débutant en Python avec une envie très particulière d'expérimenter le processus de recherche de nom de point de Python. Comment coder une classe ou une fonction dans & make; make.py " afin que ces instructions de mission fonctionnent avec succès?

import make

make.a.dot.separated.name = 666
make.something.else.up = 123
make.anything.i.want = 777
Était-ce utile?

La solution

#!/usr/bin/env python

class Make:
    def __getattr__(self, name):
        self.__dict__[name] = Make()
        return self.__dict__[name]

make = Make()

make.a.dot.separated.name = 666
make.anything.i.want = 777

print make.a.dot.separated.name
print make.anything.i.want

La méthode spéciale __ getattr __ est appelée lorsqu'une valeur nommée est introuvable. La ligne make.anything.i.want finit par faire l'équivalent de:

m1 = make.anything    # calls make.__getattr__("anything")
m2 = m1.i             # calls m1.__getattr__("i")
m2.want = 777

L’implémentation ci-dessus utilise ces appels à __ getattr __ pour créer une chaîne d’objets Créer à chaque accès à une propriété inconnue. Cela permet aux accès par points d'être imbriqués de manière arbitraire jusqu'à l'attribution finale, à laquelle une valeur réelle est affectée.

Documentation Python - personnalisation de l'accès aux attributs :

  

objet .__ getattr __ (nom, nom)

     

Appelé lorsqu'une recherche d'attribut n'a pas trouvé l'attribut aux emplacements habituels (c'est-à-dire qu'il ne s'agit pas d'un attribut d'instance ni dans l'arborescence de la classe pour self ). nom est le nom de l'attribut. Cette méthode doit renvoyer la valeur d'attribut (calculée) ou générer une exception AttributeError .

     

Notez que si l'attribut est trouvé via le mécanisme normal, __ getattr __ () n'est pas appelé. (Il s'agit d'une asymétrie intentionnelle entre __ getattr __ () et __ setattr __ () .) Cette opération est effectuée à la fois pour des raisons d'efficacité et pour d'autres raisons __ getattr __ () n'aurait aucun moyen d'accéder à d'autres attributs de l'instance. Notez qu'au moins pour les variables d'instance, vous pouvez simuler un contrôle total en n'insérant aucune valeur dans le dictionnaire des attributs d'instance (mais en les insérant dans un autre objet). Reportez-vous à la méthode __ getattribute __ () ci-dessous pour obtenir un contrôle effectif sur les classes de style nouveau.

     

objet .__ setattr __ (auto, nom, valeur)

     

Appelé lorsqu'une attribution d'attribut est tentée. Ceci est appelé à la place du mécanisme normal (c'est-à-dire stocker la valeur dans le dictionnaire d'instance). nom est le nom de l'attribut, valeur est la valeur à lui attribuer.

     

Si __ setattr __ () souhaite attribuer un attribut d'instance, il ne doit pas simplement exécuter self.name = value & # 8212; cela provoquerait un appel récursif à lui-même. Au lieu de cela, il convient d'insérer la valeur dans le dictionnaire des attributs d'instance, par exemple, self .__ dict __ [nom] = valeur . Pour les classes de style nouveau, plutôt que d'accéder au dictionnaire d'instance, il convient d'appeler la méthode de classe de base avec le même nom, par exemple, objet .__ setattr __ (self, nom, valeur) .

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top