class - Setting a functools.partial as an instance method in Python -
i'm using functools.partial
create closure, , using setattr
make callable class instance. idea here create set of methods @ runtime.
#!/usr/bin/python functools import partial class myclass(object): def __init__(self, val): self.val = val @classmethod def generatemethods(self): def dummy(conf1, self): print "conf1:", conf1 print "self.val:", self.val print s in ('dynamic_1', 'dynamic_2'): closed = partial(dummy, s) setattr(self, "test_{0}".format(s), closed)
it seems me partial
bind current value of s
dummy
's first arg, free self
passed when called instance.
it's not working how i'd expect
if __name__ == '__main__': # dynamically create methods myclass.generatemethods() # create instance x = myclass('foo') # dynamically created methods aren't callable instance :( #x.test_dynamic_1() # typeerror: dummy() takes 2 arguments (1 given) # .. these work fine myclass.test_dynamic_1(x) myclass.test_dynamic_2(x)
is possible dynamically create methods closures, callable instances of class?
the issue when you're calling them using instances not bound methods, i.e have no knowledge instance. bound methods insert self
arguments of underlying function automatically when called, stored in __self__
attribute of bound method.
so, override __getattribute__
, see if object being fetched instance of partial
type or not, if yes, convert bound method using types.methodtype
.
code:
#!/usr/bin/python functools import partial import types class myclass(object): def __init__(self, val): self.val = val @classmethod def generatemethods(self): def dummy(conf1, self): print "conf1:", conf1 print "self.val:", self.val print s in ('dynamic_1', 'dynamic_2'): closed = partial(dummy, s) setattr(self, "test_{0}".format(s), closed) def __getattribute__(self, attr): # here have access need instance(self) obj = object.__getattribute__(self, attr) if isinstance(obj, partial): return types.methodtype(obj, self, type(self)) else: return obj if __name__ == '__main__': myclass.generatemethods() x = myclass('foo') x.test_dynamic_1() x.test_dynamic_2()
Comments
Post a Comment