2012-03-16 5 views
2

Laissez-moi commencer par dire ce que je voudrais faire. Je veux créer un wrapper paresseux pour une variable, comme dans I enregistrer tous les appels de méthode et les opérateurs et les évaluer plus tard quand je spécifie la variable pour l'appeler. En tant que tel, je veux être en mesure d'intercepter tous les appels de méthode et les appels opérateur et les méthodes spéciales afin que je puisse travailler dessus. Cependant, __getattr__ n'intercepte pas les appels d'opérateur ou __str__ et ainsi de suite, donc je veux savoir s'il y a une manière générique de surcharger tous les appels de méthode, ou devrais-je créer dynamiquement une classe et dupliquer le code pour tout cela (que je déjà fait, mais est moche).Python interception méthode appel

+1

J'ai écrit une réponse à [cette question] (http://stackoverflow.com/questions/9057669/how-can-i-intercept-calls-to-pythons-magic-methods-in-new-style-classes/9059858 # 9059858) qui est similaire à ce que vous voulez faire. – kindall

+0

Même __getattribute__ n'est pas appelé sur les méthodes dunder. Drat. –

Répondre

0

Cela peut être fait, mais oui, il devient "moche" - j'ai écrit une fois un décorateur paresseux, qui transforme n'importe quelle fonction en une "fonction paresseusement calculée".

Fondamentalement, j'ai découvert que le seul moment où la valeur d'un objet est réellement utilisée dans Python est quand l'une des méthodes spéciales "dunder" est appelée. Par exemple, lorsque vous avez un nombre, sa valeur n'est utilisée que lorsque vous l'utilisez dans une autre opération ou la convertissez en chaîne pour IO (qui utilise également une méthode "dunder")

Alors, mon wrapper anote les paramètres à un appel de fonction et renvoie un objet spécial, qui a potentiellement toutes les méthodes "dunder". Juste au moment où l'une de ces méthodes est appelée, la fonction d'origine est appelée - et sa valeur de retour est ensuite mise en cache pour une utilisation ultérieure.

La mise en œuvre est ici: https://bitbucket.org/jsbueno/metapython/src/510a7d125b24/lazy_decorator.py

Désolé pour le texte et la plupart de la présentation étant en portugais.

+0

Vous avez raison, '__getattribute__' n'est pas appelé sur les méthodes dunder. –