How to make a function a bound method

Question:

I have a class that reads a string and for each character of the string, perform a certain action. I want my class to be able to be supplied with custom actions to extend it’s functionality. In order to do that, I want to make user supplied functions a bounded method of my class, so that I can loop over string like this;

for x in self.string:
    getattr(self, self.actions[x])()

I have tried this to make new bound methods for my class:

class myclass(object):

    def __init__(self, additional_actions={}):
        self.thing = "value"
        for k,v in additional_actions.items():
            setattr(self,k,v)


def dummy(self):
    print(self.thing)

mydic = {"awesome":dummy}

a = myclass(mydic)
a.awesome()

However, I get this error:

Traceback (most recent call last):
  File "<pyshell#2>", line 1, in <module>
    a.awesome()
TypeError: dummy() missing 1 required positional argument: 'self'

How can I turn a regular function into a bound method?

Asked By: yasar

||

Answers:

That’s something you’ll want to latch onto the class to make it bound, not the instance of the class. If you want to only do it on an instance-by-instance basis you’ll have to use types.MethodType. See: https://filippo.io/instance-monkey-patching-in-python/

It is very likely that there is a better way of accomplishing what you want to do, though. Monkey patching in Python is considered a very poor pattern 99% of the time.

Answered By: Anorov

Assign method on a single instance

import types

a = myclass()
setattr(a, "awesome", types.MethodType(dummy, a))
a.awesome()

Add method to a class

setattr(myclass, "awesome", dummy)

a = myclass()
a.awesome()

b = myclass()
b.awesome()

Now each instance would have same method available

Answered By: Misha Brt
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.