Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to pass an instance method, that uses instance variables, as argument to another function?

I want to pass a method foo of an instance of a class A to another function run_function. The method foo will use instance variables of its class A.

Here is a minimal example, in which the instance variable of A is simply self.a_var, and foo just prints that variable.

class A:
    def __init__(self,a_var):
        self.a_var=a_var
    def foo(self):
        print(self.a_var)


class B:
    def __init__(self, A):
        self.A=A

        # EDIT (comment to compile)
        self.A.do_something()

    def run_function(self):
        self.A.foo()
    def run_function_2(self, bar):
        bar()



myA = A(42)
myA.foo()

# Current implementation
myB=B(myA)
myB.run_function()

# Better(?) implementation
myB.run_function_2(myA.foo)

At the moment I pass the instance myA of class A to the instance of B and explicitly call self.A.foo(). This forces the name of the function of Ato be foo. Which is stupid.

The better (?) implementation passes the function of the instance to run_function2. This works, but I am not sure if this is "safe".

Question:

Are there any loopholes that I don't see at the moment?

The important part is, that the method foo, that is passed, needs to access instance variables of the (its) class instance. So, will foo that is called inside run_function_2 always have access to all instance variables of myA?

Is there a better way to implement this?

EDIT: I forgot to add, that class B will always have an instance of A, since it has to do_something with that instance. Maybe that will change something(?). Sorry!

like image 308
P. Siehr Avatar asked Jan 19 '26 10:01

P. Siehr


1 Answers

For your second implementation, have you considered the following:

>>> myAa = A(42)
>>> myAb = A(43)
>>> myB = B(myAb)
>>> myB.run_function_2(myAa.foo)
42

This might not be what you want. How about using getattr() and just passing in the desired method name:

>>> class C:
...     def __init__(self, A):
...             self.A = A
...     def run_fct(self, bar):
...             fct = getattr(self.A, bar)
...             fct()
... 
>>> myC = C(myAa)
>>> myC.run_fct('foo')
42
like image 55
bgse Avatar answered Jan 20 '26 23:01

bgse