简体   繁体   中英

How to define a custom function of an instance using setattr

I'm trying to add a method to a class dynamically, but I keep running into an error where self is not passed to a the new function. For instance:

class Dummy():
    def say_hi(self):
        print("hi")


def new_method(self):
    print("bye")


dummy = Dummy()
setattr(dummy, "say_bye", new_method)

dummy.say_bye()

results in the following error:

Traceback (most recent call last):
  File "main.py", line 13, in <module>
    dummy.say_bye()
TypeError: new_method() missing 1 required positional argument: 'self'

What am I doing wrong?

Use types.MethodType feature:

from types import MethodType

class Dummy():
    def say_hi(self):
        print("hi")


def new_method(self):
    print("bye")


dummy = Dummy()
dummy.say_bye = MethodType(new_method, dummy)

dummy.say_bye()   # bye

You are setting the function new_method as an attribute of the dummy object.

If you do print(dummy.__dict__) you'll see something like this:

{'say_bye': <function new_method at 0x7fcd949af668>}

This means that your dummy object has the function new_method as an attribute, so when you do dummy.say_bye() , you're calling the function you have as an attribute without any argument.

It is not a function of the Dummy class, it is just a function that your dummy object has as an attribute.

You can achieve the functionality you are looking for using RomanPerekhrest's answer.

Hope it helps.

Cheers!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM