oop - How to catch any method called on an object in python? -
i'm looking pythonic solution on how store method called on object right inside object.
because in python, if want catch example abs()
method, overload operator like:
catcher(object): def __abs__(self): self.function = abs c = catcher() abs(c) # c.function stores 'abs' called on c
if want catch function, have other attribute in it, example pow()
, i'm going use this:
catcher(object): def __pow__(self, value): self.function = pow self.value = value c = catcher() c ** 2 # c.function stores 'pow', , c.value stores '2'
now, i'm looking general solution, catch , store kind of function called on catcher
, without implementing overloads, , other cases. , can see, want store values (maybe in list, if there more 1 of them?) attributes of method.
thanks in advance!
a metaclass won't here; although special methods looked on type of current object (so class instances), __getattribute__
or __getattr__
not consulted when doing (probably because special methods). catch all dunder methods, forced create them all.
you can pretty decent list of operator special methods (__pow__
, __gt__
, etc.) enumerating operator
module:
import operator operator_hooks = [name name in dir(operator) if name.startswith('__') , name.endswith('__')]
armed list class decorator be:
def instrument_operator_hooks(cls): def add_hook(name): operator_func = getattr(operator, name.strip('_'), none) existing = getattr(cls, name, none) def op_hook(self, *args, **kw): print "hooking {}".format(name) self._function = operator_func self._params = (args, kw) if existing not none: return existing(self, *args, **kw) raise attributeerror(name) try: setattr(cls, name, op_hook) except (attributeerror, typeerror): pass # skip __name__ , __doc__ , hook_name in operator_hooks: add_hook(hook_name) return cls
then apply class:
@instrument_operator_hooks class catchall(object): pass
demo:
>>> c = catchall() >>> c ** 2 hooking __pow__ traceback (most recent call last): file "<stdin>", line 1, in <module> file "<stdin>", line 11, in op_hook attributeerror: __pow__ >>> c._function <built-in function pow> >>> c._params ((2,), {})
so, though our class doesn't define __pow__
explicitly, still hooked it.
Comments
Post a Comment