【问题标题】:Can you pass a variable by reference to a callback method in python?你可以通过引用python中的回调方法来传递变量吗?
【发布时间】:2015-03-09 05:50:33
【问题描述】:

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

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 还很陌生,所以我不太熟悉它如何处理通过引用传递参数。我错过了什么?

感谢您的宝贵时间。

【问题讨论】:

  • Python 按值传递参数。然而,python 中的 all 值只是对对象的引用。您可以说发生的情况是它是通过 copy 的引用传递的。希望,如果您考虑一下这个问题,您会更好地理解发生了什么。

标签: python user-interface callback tkinter event-handling


【解决方案1】:

当你这样做时:

filePath = event.widget.get()

您正在将局部变量filepath 的值从传递给函数的值更改为event.widget.get() 返回的值。此时传递给函数的值丢失了。

您不能分配给以这种方式传入的调用者变量。一方面,如果他们没有传入变量怎么办?

大多数情况下的常见做法是简单地返回值。如果这是不可能的,因为在这种情况下不是这样,您可以让您的函数采用一个可变容器,例如列表、字典或类实例,并对其进行修改。 tkinter 为各种基本类型提供了这样的可变类,例如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 程序员更喜欢这种可能性)是使您的回调函数成为某个类实例上的绑定方法。然后,您可以将该值作为属性存储在实例上。这样做的好处是该方法已经知道它连接到什么对象(通过self),因此您不需要明确地处理它。既然你只需要一个方法,那就让实例可调用吧!

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

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

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

要稍后检索该值,请引用 inputFilePath.value。您甚至可以修饰 StrHolder 类,使其或多或少像字符串一样工作,而无需引用属性。

【讨论】:

  • 在绑定中返回某些内容不是一种常见的做法。绑定的调用者(事件循环)丢弃绑定函数的返回值。
  • 那么,如何确保Entry 字段中的新数据将分配给inputFilePath 变量?
  • 已更新,希望对您有所帮助。
猜你喜欢
  • 2011-02-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-16
  • 2013-11-13
  • 1970-01-01
相关资源
最近更新 更多