0

I have a class:

class A(object):
    def __init__(self):
        self._first=1
    def a(self):
        pass

I want to dynamically add a method to it, but I want the name to be based on input (in my case, based on coded object attributes, but that's besides the point). So, I'm adding methods using the below:

#Set up some variables
a = "_first"
b = "first"
d = {}
instance = A()

#Here we define a set of symbols within an exec statement 
#and put them into the dictionary d
exec "def get_%s(self): return self.%s" % (b, a) in d

#Now, we bind the get method stored in d to our object
setattr(instance, d['get_%s' % (b)].__name__, d['get_%s' % (b)])

This all works fine, with one caveat:

#This returns an error
>>> print(instance.get_first())
 Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
 TypeError: get_first() takes exactly 1 argument (0 given)

#This works perfectly fine
>>> print(instance.get_first(instance))
 1

Why isn't my instance passing itself to it's new function?

Alex Barry
  • 415
  • 1
  • 9
  • 21
  • So I need to bind the function to the object with: d['get_%s' % (b)].__get__(d['get_%s' % (b)], A)? – Alex Barry Jun 11 '16 at 00:48
  • Right, all you have otherwise is a function that takes one argument, that you coincidentally named `self`, but that name is not itself magical in any way, and the function doesn't know that it's "part of" an instance unless you bind it to it – Eric Renouf Jun 11 '16 at 00:51

0 Answers0