2

Let me start by saying what I would like to do. I want to create a lazy wrapper for a variable, as in I record all the method calls and operator calls and evaluate them later when I specify the variable to call it on.

As such, I want to be able to intercept all the method calls and operator calls and special methods so that I can work on them. However, __getattr__ doesn't intercept operator calls or __str__ and such, so I want to know if there is a generic way to overload all method calls, or should I just dynamically create a class and duplicate the code for all of it (which I already did, but is ugly).

Ethan Furman
  • 63,992
  • 20
  • 159
  • 237
norcalli
  • 1,215
  • 2
  • 11
  • 22
  • 1
    I wrote an answer to [this question](http://stackoverflow.com/questions/9057669/how-can-i-intercept-calls-to-pythons-magic-methods-in-new-style-classes/9059858#9059858) that is similar to what you want to do. – kindall Mar 16 '12 at 00:31
  • Not even `__getattribute__` is called on the dunder methods. Drat. – Ethan Furman Mar 16 '12 at 04:20

1 Answers1

1

It can be done, but yes, it becomes "ugly" - I wrote a lazy decorator once, that turns any function into a "lazily computed function".

Basically, I found out that the only moment an object's value is actually used in Python is when one of the special "dunder" methods s called. For example, when you have a number, it's value is only used when you are either using it in another operation, or converting it to a string for IO (which also uses a "dunder" method)

So, my wrapper anotates the parameters to a function call, and returns an special object, which has potentially all of the "dunder" methods. Just when one of those methods is called, the original function is called - and its return value is then cached for further usage.

The implementation is here: https://bitbucket.org/jsbueno/metapython/src/510a7d125b24/lazy_decorator.py

Sorry for the text and most of the presentation being in Portuguese.

jsbueno
  • 99,910
  • 10
  • 151
  • 209