I'm looking for a pythonic solution on how to store a method which is called on an object right inside the object.
Because in python, if I want to catch for example the abs()
method, I will overload this operator like:
Catcher(object):
def __abs__(self):
self.function = abs
c = Catcher()
abs(c) # Now c.function stores 'abs' as it was called on c
If I want to catch a function, which have an other attribute in it, for example pow()
, I'm going to use this:
Catcher(object):
def __pow__(self, value):
self.function = pow
self.value = value
c = Catcher()
c ** 2 # Now c.function stores 'pow', and c.value stores '2'
Now, what I'm looking for is a general solution, to catch and store any kind of function called on Catcher
, without implementing all overloads, and other cases. And as You can see, I also want to store the values (maybe in a list, if there is more than one of them?) which are the attributes of a method.
Thanks in advance!
This is a way to do it.
Now all the calls to
test1
andtest2
will be registers in thecalls
list
.decorate_methods
applies a decorator to each method of the class.register_calls
registers the calls to the methods incalls
, with the name of the function and the arguments.A metaclass won't help here; although special methods are looked up on the type of the current object (so the class for instances),
__getattribute__
or__getattr__
are not consulted when doing so (probably because they are themselves special methods). So to catch all dunder methods, you are forced to create them all.You can get a pretty decent list of all operator special methods (
__pow__
,__gt__
, etc.) by enumerating theoperator
module:Armed with that list a class decorator could be:
Then apply that to your class:
Demo:
So, even though our class doesn't define
__pow__
explicitly, we still hooked into it.