如何将使用实例变量的实例方法作为另一个函数的参数传递?

时间:2017-08-15 14:15:03

标签: python python-3.x

我想将类foo的实例的方法A传递给另一个函数run_function。方法foo将使用其类A的实例变量。

这是一个最小的示例,其中A的实例变量只是self.a_var,而foo只打印该变量。

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)

目前,我将类myA的实例A传递给B的实例并明确调用self.A.foo()。这会强制A函数的名称为foo。这是愚蠢的。

更好的(?)实现将实例的功能传递给run_function2。这有效,但我不确定这是否安全"。

问题:

目前我还没有看到任何漏洞吗?

重要的是,传递的方法foo需要访问(其)类实例的实例变量。那么,在foo内调用的run_function_2是否始终可以访问myA的所有实例变量?

有没有更好的方法来实现这个?

编辑:我忘了添加,class B将始终拥有A的实例,因为它必须do_something具有该实例。也许这会改变一些事情(?)。遗憾!

3 个答案:

答案 0 :(得分:2)

回答你的问题:

  1. 在对象实例的上下文中执行的任何函数都可以访问实例变量。
  2. 可能有更好的方法来实现它,您可以尝试为类A和其他可能类似的类定义接口。你知道该函数将永远被称为foo()。如果没有,我会问为什么你需要让一些对象调用另一个对象上的任意方法。如果你能提供更多具体的例子来说明你要做什么,那就会有所帮助。

答案 1 :(得分:1)

对于第二次实施,您是否考虑过以下事项:

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

这可能不是你想要的。如何使用getattr()并传递所需的方法名称:

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

答案 2 :(得分:0)

run_functionrun_function_2之间的主要区别在于前者在赋予foo构造函数的对象上调用B()run_function_2与保存为self.A的对象无关;它只是调用你给它的函数/方法。例如

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
    def run_function(self):
        self.A.foo()
    def run_function_2(self, bar):
        bar()

myA = A(42)
myB = B(myA)
myA2 = A(3.14)

myB.run_function()
myB.run_function_2(myA.foo)
myB.run_function_2(myA2.foo)

输出

42
42
3.14
  

目前我还没有看到任何漏洞吗?

这两种调用方法的方法都很好。虽然我同意function_run_2更方便,因为它没有修复方法名称,但它会让你问......给A构造函数赋予B对象的目的是什么?如果从未使用过它的第一个地方?

  

重要的是,传递的方法foo需要访问(它)类实例的实例变量。那么,在run_function_2内调用的foo是否总能访问myA的所有实例变量?

是。 run_function_2个参数需要一个函数。在这种情况下,您传递myA.foomyA中定义的对象class A的方法。当您在foo内调用run_function_2时,您只处理实例myA的属性变量;这是在类中封装的想法。

  

有没有更好的方法来实现这个?

还回答你关于安全的问题,这是非常安全的。函数和方法是Python中的对象,它们可以像值一样传递。你基本上倾向于函数currying或部分函数的想法。见How do I pass a method as a parameter in Python。这两种方式都很好。