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

Popular posts from this blog

php - Zend Framework / Skeleton-Application / Composer install issue -

c# - Better 64-bit byte array hash -

python - PyCharm Type error Message -