Set a class function with parameters as an Attribute
Sometimes we have to set/inject/monkey patch attributes or functions to objects. This is fairly simple when we have the instance or the class and we don't need to pass any parameters. In that case we would do:
class Foo(object): def bar(self): print 'bar' def foo(self): print 'foo' self.bar() # You can set the attribute by doing: setattr(Foo, 'foo', foo) # or Foo.foo = foo
Then once you create and instance of Foo you can call the foo.
foo_instance = Foo() foo_instance.foo() # This will print 'foo' and 'bar'.
All this is pretty simple and you can also do the same with an instance, but how about setting a function that receives parameters? In that case you need to use a wrapper.
from functools import wraps def partial(func, *parameters, **kparms): @wraps(func) def wrapper(*args, **kwargs): kw.update(kparms) return func(*(args + parameters), **kwargs) return wrapper
This would allow you to do things like:
def dynamic_foo(self, value1, *args, **kwargs): print value1 print args print kwargs self.bar() setattr(Foo, 'foo1', partial(dynamic_foo, 'this is foo 1')) setattr(Foo, 'foo2', partial(dynamic_foo, 'this is foo 2', 'value 1', 'value 2')) setattr(Foo, 'bar_x', partial(dynamic_foo, 'this is bar x', val1='value 1', val2='value 2'))
As you can see this is setting dynamic functions to Foo with different parameter values. This allow you to do:
foo_instance = Foo() foo_instance.foo1() # This will print: # 'this is foo 1' # () # {} # 'bar' foo_instance.foo2() # This will print: # 'this is foo 2' # ('value 1', 'value 2') # {} # 'bar' foo_instance.bar_x() # This will print: # 'this is bar x' # () # {'val1': 'value 1', 'val2': 'value 2'} # 'bar'
Cheers.









