您可以通过引用 python 中的回调方法传递变量吗?

Can you pass a variable by reference to a callback method in python?

我正在使用 Python 3 中的 tkinter 开发 GUI,我有一个名为 inputFilePathDisplayEntry 文本框,具有以下绑定:

inputFilePathDisplay.bind("<Key>", lambda event, filePath = inputFilePath: key(event, filePath))

我有以下按键按下时的回调函数:

#input functions -- see if the user has entered text
def key(event, filePath):
    filePath = event.widget.get()

我的目标是获取 Entry 框中的输入并将其分配给 inputFilePath。我可以看到 filePath 变量在 key() 函数中发生了变化,但是 inputFilePath 的值没有更新。我是 Python 的新手,所以我不太熟悉它如何处理按引用传递参数。我缺少什么?

感谢您的宝贵时间。

当你这样做时:

filePath = event.widget.get()

您正在将局部变量 filepath 的值从传递给函数的值更改为由 event.widget.get() 编辑的值 return。传入函数的值此时丢失。

您不能对以这种方式传入的调用方变量进行赋值。一方面,如果他们不传入变量怎么办?

大多数情况下的常见做法是 return 该值。如果这是不可能的,因为在这种情况下是不可能的,您可以让您的函数采用一个可变容器,例如列表、字典或 class 实例,然后对其进行修改。 tkinter 为各种基本类型提供了这样的可变 classes,例如 StringVar.

因此,您定义了一个 StringVar 实例,您使用 set() 方法设置它的值,然后您可以稍后使用 get().

检索它

因此您的 key 函数如下所示:

def key(event, filePath):
    filePath.set(event.widget.get())

您的绑定如下所示:

inputFilePath = StringVar()
inputFilePathDisplay.bind("<Key>", lambda event, filePath=inputFilePath: key(event, filePath))

另一种可能性(通过快速谷歌搜索,我发现许多 tkinter 程序员更喜欢这种可能性)是使您的回调函数成为某些 class 实例上的绑定方法。然后您可以将该值作为属性存储在实例上。这样做的好处是该方法已经知道它连接到什么对象(通过 self),因此您不需要明确地处理它。由于您只需要一个方法,让我们将实例设为可调用!

class StrHolder(object):
    def __call__(self, event):
        self.value = event.widget.get()

现在您的绑定可以是,例如:

inputFilePath = StrHolder()
inputFilePathDisplay.bind("<Key>", inputFilePath)

稍后要检索值,请参考 inputFilePath.value。您甚至可以美化 StrHolder class,因此它或多或少像字符串一样工作,而无需引用属性。