2

I am working in a dynamic programming environment where I might need to define (or redefine) a class function. So consider this for example:

def func(self):
    print("hello2 \n")

class ManClass:
    def __init__(self):
        pass
    def func1(self):
        print("hello1\n")

a = ManClass()

a.func1()
hello1

a.func2 = func
>>> a.func2()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: func() takes exactly 1 argument (0 given)

If func2() had been defined inside the class - a.func2() would have been interpreted as ManClass.func2(a) - but now that I am assigning it outside, it seems to expect an argument. How do I fix this, but more importantly, why this difference in how the two definitions are interpereted ?

2 Answers 2

2

You didn't add func to the class, you added it to an instance. Try ManClass.func2 = func instead.

a.func2 = func adds func to the a instance of the class as an instance attribute named func2, not as an instance member method (which is really just special handling for callable members on the underlying class object).

Alternatively, you can also add a member method to a single instance using MethodType, as @jonrsharpe points out in his answer.

Sign up to request clarification or add additional context in comments.

1 Comment

Oh snap, you're right. Class and instance attributes/functions are 'different'. I should've known what I was doing wrong. Thanks a lot !
2

This is the difference between a function and a bound method, where "bound" refers to the instance self. To fix your problem, you need to make the standalone function MethodType:

from types import MethodType

a.func2 = MethodType(func, a)

This binds the func to the ManClass instance a, allowing it to access any instance attributes. Note that this only affects a, other ManClass instances will retain the original class definition unless similarly patched.

When you simply attach the function

a.func2 = func

you can still access it:

a.func2(None) # will print "hello2 \n"

But it doesn't get the implicit object instance self parameter and just treats it as a standard positional argument.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.