我想将类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
具有该实例。也许这会改变一些事情(?)。遗憾!
答案 0 :(得分:2)
回答你的问题:
答案 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_function
和run_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.foo
,myA
中定义的对象class A
的方法。当您在foo
内调用run_function_2
时,您只处理实例myA
的属性变量;这是在类中封装的想法。
有没有更好的方法来实现这个?
还回答你关于安全的问题,这是非常安全的。函数和方法是Python中的对象,它们可以像值一样传递。你基本上倾向于函数currying或部分函数的想法。见How do I pass a method as a parameter in Python。这两种方式都很好。