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?
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.
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
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?
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.
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