Reputation: 22726
I'm using a 3rd party API that provides a single Python wrapper class which contains ~50 methods that do nothing except accepting a set of arbitrary parameters. I am then meant to make my own class and override each of those methods to do what I actually want. My issues with this:
Stripped down version of their class:
class TheirWrapper:
def __init__(self):
pass
def func1(self, a, b, c):
pass
def func2(self, d, e, f):
pass
... and ~50 more
And stripped down version of what I have working:
class MyWrapper:
def addToQueue(self, localvars):
# adds calling function name and localvars to queue (after removing self from localvars)
def func1(self, a, b, c):
self.addToQueue(locals())
def func1=2(self, d, e, f):
self.addToQueue(locals())
... and ~50 more
Considering that I do precisely the same thing in each overridden method (self.addToQueue(locals())
), I would like to be able to override ALL of their methods at once (except __init__
) to do that one thing. Is such a thing possible?
Upvotes: 4
Views: 1051
Reputation: 8550
Here is a possible way to do it using inspection of contents of TheirWrapper
with dir()
:
import inspect
class TheirWrapper:
def __init__(self):
pass
def func1(self, a, b, c):
pass
def func2(self, d, e, f):
pass
class MyWrapper:
def addToQueue(self, localvars):
# your implementation
print(localvars)
### You can orginize this block into decorator or metaclass and make more general
def add_func(func_name):
def add(self, *args, **kwargs):
signature = inspect.signature(getattr(TheirWrapper, func_name))
bind = signature.bind(self, *args, **kwargs)
arguments = dict(bind.arguments)
arguments['func_name'] = func_name
self.addToQueue(arguments)
return add
for name in dir(TheirWrapper):
if not name.startswith('__'):
setattr(MyWrapper, name, add_func(name))
###
w = MyWrapper()
w.func1(1, 2, 3)
# prints {'self': <__main__.MyWrapper object at 0x00000000030262E8>, 'a': 1, 'b': 2, 'c': 3, 'func_name': 'func1'}
docs for inspect.signature & bind
Upvotes: 4