[英]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
. 我想将类A
的实例的方法foo
传递给另一个函数run_function
。 The method foo
will use instance variables of its class A
. 方法foo
将使用其类A
实例变量。
Here is a minimal example, in which the instance variable of A
is simply self.a_var
, and foo
just prints that variable. 这是一个最小的例子,其中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)
At the moment I pass the instance myA
of class A
to the instance of B
and explicitly call self.A.foo()
. 目前,我将类A
的实例myA
传递给B
的实例,并显式调用self.A.foo()
。 This forces the name of the function of A
to be foo
. 这会强制A
的函数名称为foo
。 Which is stupid. 这是愚蠢的。
The better (?) implementation passes the function of the instance to run_function2
. 更好的(?)实现将实例的功能传递给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. 重要的是,传递的方法foo
需要访问(它)类实例的实例变量。 So, will foo
that is called inside run_function_2
always have access to all instance variables of myA
? 因此,将foo
那个叫内run_function_2
始终可以访问所有实例变量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. 编辑:我忘了添加, class B
将始终有一个A
的实例,因为它必须与该实例做do_something
。 Maybe that will change something(?). 也许这会改变一些事情(?)。 Sorry! 抱歉!
To answer your questions: 回答你的问题:
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: 如何使用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
The main difference between run_function
and run_function_2
is that the former calls foo
on the object that was given to the B()
constructor. run_function
和run_function_2
之间的主要区别在于前者在给予B()
构造函数的对象上调用foo
。 run_function_2
is independent of what object is saved as self.A
; run_function_2
独立于保存为self.A
对象; it just calls the function/method you give it. 它只是调用你给它的函数/方法。 For example 例如
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)
Output 产量
42
42
3.14
Are there any loopholes that I don't see at the moment? 我目前没有看到任何漏洞吗?
These two ways of calling methods are fine. 这两种调用方法的方法都很好。 Though I agree that function_run_2
is more convenient since it doesn't fix the method name, it makes you ask... what's the purpose of giving an A
object to the B
constructor in the first place if it's never used? 虽然我同意function_run_2
更方便,因为它没有修复方法名称,但是它会让你问......如果A
对象从未使用过,它首先给B
构造函数提供了什么目的?
The important part is, that the method foo, that is passed, needs to access instance variables of the (its) class instance. 重要的是,传递的方法foo需要访问(它)类实例的实例变量。 So, will foo that is called inside run_function_2 always have access to all instance variables of myA? 那么,在run_function_2里面调用的foo总能访问myA的所有实例变量吗?
Yes. 是。 run_function_2
arguments requires a function. run_function_2
参数需要一个函数。 In this case, you pass myA.foo
, an object myA
's method defined in class A
. 在这种情况下,您传递myA.foo
,这是在class A
定义的对象myA
的方法。 When you call foo
inside run_function_2
, you are only dealing with attributes variables of the instance myA
; 当你在run_function_2
调用foo
,你只处理实例myA
属性变量; this is the idea of encapsulation in classes. 这是在类中封装的想法。
Is there a better way to implement this? 有没有更好的方法来实现这个?
Answering also your question on safety, it's perfectly safe. 回答你关于安全的问题,这是非常安全的。 Functions and methods are objects in Python, and they can be passed around like values. 函数和方法是Python中的对象,它们可以像值一样传递。 You're basically leaning on the idea of function currying or partial functions. 你基本上倾向于函数currying或部分函数的想法。 See How do I pass a method as a parameter in Python . 请参见如何在Python中将方法作为参数传递 。 These two ways are fine. 这两种方式都很好。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.