Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamically assigning function implementation in Python

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.

like image 556
Yarin Avatar asked Apr 29 '12 17:04

Yarin


People also ask

How do you create a dynamic function in Python?

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.

How do you assign a value to a dynamic function in Python?

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.

How do you make a function run automatically in Python?

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()!")

How do you pass a dynamic argument in Python?

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.


2 Answers

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

like image 100
yak Avatar answered Oct 21 '22 12:10

yak


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)
like image 33
Amber Avatar answered Oct 21 '22 14:10

Amber



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!