16

When I do the following:

class C:
 pass

def f( self ):
 print self

a = C()

a.f = f

a.f()

I get the following error at the line a.f(): TypeError: f() takes exactly 1 argument (0 given)

The problem appears to be that when f is added to the instance, a, it is treated like a function that is stored inside of a, rather than an actual member function. If I change a.f() to a.f(a), then I get the intended effect, but is there a way to make python interpret the original example this way? In other words, is there a way to add a member function to an instance of a class at runtime?

Thanks

Harold Forrest
  • 163
  • 1
  • 4

2 Answers2

26

For Python 2.X you can use:

import types
class C:
    pass

def f(self):
    print self

a = C()
a.f = types.MethodType(f,a)
a.f()

For Python 3.X:

import types
class C(object):
    pass

def f(self):
    print(self)

a = C()
a.f = types.MethodType(f,a)
a.f()
GWW
  • 43,129
  • 11
  • 115
  • 108
  • 3
    This is the way to add the function to the specific instance `a` (other instances of class `C` won't have `f`). – Dave Jul 13 '12 at 15:33
  • 2
    `C.f = types.MethodType(f,None,C)` would be the code to add the function to any existing or eventual new instances of the class C – Jules G.M. Mar 31 '14 at 01:24
  • What python version is this for? the `print` statement suggest python 2.*. Doesnt work in python 3. – LudvigH Aug 21 '19 at 09:41
  • 1
    @LudvigH: I have modified my answer to include support for python 3.X. – GWW Aug 21 '19 at 15:00
  • No problem. Thanks for pointing this out it's hard to remember if old answers need to be updated. – GWW Aug 21 '19 at 15:04
5

You should put f in the class, not in the instance...

 class C:
     pass

 def f(self):
    print(self)

 a = C()
 C.f = f
 a.f()

For the interpreter myObject.foo() is the same as myClass.foo(myObject) when the object doesn't hold anything named foo, but a function placed inside a object is just a function.

JBernardo
  • 32,262
  • 10
  • 90
  • 115
  • 4
    This is the way to add the function to all instances of class `C` (and it's sub-classes). – Dave Jul 13 '12 at 15:34