I want to assign a function implementation dynamically.
Let's start with the following:
class Doer(object):
def __init__(self):
self.name = "Bob"
def doSomething(self):
print "%s got it done" % self.name
def doItBetter(self):
print "Done better"
In other languages we would make doItBetter an anonymous function and assign it to the object. But no support for anonymous functions in Python. Instead, we'll try making a callable class instance, and assign that to the class:
class Doer(object):
def __init__(self):
self.name = "Bob"
class DoItBetter(object):
def __call__(self):
print "%s got it done better" % self.name
Doer.doSomething = DoItBetter()
doer = Doer()
doer.doSomething()
That gives me this:
Traceback (most recent call last): Line 13, in doer.doSomething() Line 9, in call print "%s got it done better" % self.name AttributeError: 'DoItBetter' object has no attribute 'name'
Finally, I tried assigning the callable to the object instance as an attribute and calling it:
class Doer(object):
def __init__(self):
self.name = "Bob"
class DoItBetter(object):
def __call__(self):
print "%s got it done better" % self.name
doer = Doer()
doer.doSomething = DoItBetter()
doer.doSomething()
This DOES work as long as I don't reference self in DoItBetter, but when I do it gives me an name error on self.name because it's referencing the callable's self, not the owning class self.
So I'm looking for a pythonic way to assign an anonymous function to a class function or instance method, where the method call can reference the object's self.
Python Code can be dynamically imported and classes can be dynamically created at run-time. Classes can be dynamically created using the type() function in Python. The type() function is used to return the type of the object. The above syntax returns the type of object.
The creation of a dynamic variable name in Python can be achieved with the help of iteration. Along with the for loop, the globals() function will also be used in this method. The globals() method in Python provides the output as a dictionary of the current global symbol table.
Add self. initialize() to myfunc() , this should do what you are looking for. class MyClass(object): def __init__(self): pass def initialize(self): print("I'm doing some initialization") def myfunc(self): self. initialize() print("This is myfunc()!")
Dynamic Function Arguments Passing arguments to the dynamic function is straight forward. We simply can make solve_for() accept *args and **kwargs then pass that to func() . Of course, you will need to handle the arguments in the function that will be called.
Your first approach was OK, you just have to assign the function to the class:
class Doer(object):
def __init__(self):
self.name = "Bob"
def doSomething(self):
print "%s got it done" % self.name
def doItBetter(self):
print "%s got it done better" % self.name
Doer.doSomething = doItBetter
Anonymous functions have nothing to do with this (by the way, Python supports simple anonymous functions consisting of single expressions, see lambda).
yak's answer works great if you want to change something for every instance of a class.
If you want to change the method only for a particular instance of the object, and not for the entire class, you'd need to use the MethodType type constructor to create a bound method:
from types import MethodType
doer.doSomething = MethodType(doItBetter, doer)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With