Metaprogramming in Python - Adding an Object Method

I have experience working in Python (although I am completely self-taught, so I may have some bad habits or misconceptions), and I'm trying to learn Ruby to expand the scope.

I read some comparisons and saw many claims that “Python cannot metaprogram” (or, less inflammatory, “Python cannot metaprogram as simple as Ruby”). So I left and quickly read about metaprogramming, and left with the impression that this is mainly editing the methods / behavior of your classes / objects at runtime (please correct me if I'm wrong!).

I got the impression that since Python is dynamic this should not be a problem. However, I ran the following test code that did not give the expected answer:

>>> class foo: ... def make_hello_method(self): ... def hello(obj): ... print 'hello' ... self.hello = hello ... >>> f = foo() >>> f.hello() Traceback (most recent call last): File "<stdin>", line 1, in <module> AttributeError: foo instance has no attribute 'hello' >>> f.make_hello_method() >>> f.hello() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: hello() takes exactly 1 argument (0 given) 

I had the impression that each method of the object automatically passed the object itself as the first argument (hence, the constant requirements for defining object methods as (self, [...]) ). Why is f not passed to hello() ?

+6
source share
2 answers

You need to do this with the instance method. There is a class for this in the types module. This will work:

 self.hello = types.MethodType(hello, self) 
+5
source

Seeing that you are using Python 2, you can use the new module to do this job:

 self.hello = new.instancemethod(hello, self, foo) 
+2
source

All Articles