为啥 Kivy 需要括号,而 Python 不需要括号?

Posted

技术标签:

【中文标题】为啥 Kivy 需要括号,而 Python 不需要括号?【英文标题】:Why are parentheses needed in Kivy but not in Python?为什么 Kivy 需要括号,而 Python 不需要括号? 【发布时间】:2014-08-09 08:33:02 【问题描述】:

如果我想在任何程序的弹出窗口中添加on_press 事件,我可以直接在 python 中或使用 kv 语言来完成。

如果我使用 Python,例如

from kivy.app import App
from kivy.uix.popup import Popup
from kivy.uix.button import Button

class SomePopup(Popup):
    pass

class SomeBox(Box):
    popup = SomePopup()
    popup.title = 'anything'
    popup.content = Button(text='anytext', on_press=popup.dismiss)

在 KV 语言中,假设我制作相同的弹出窗口,它会是。

<SomePopup>
    title: 'anything'
    content: popupContent
    Button:
        id: popupContent
        text: 'anytext'
        on_press: root.dismiss()

所以,在 python 中,我必须使用 on_press=popup.dismiss 和 kv 语言 on_press: root_dismiss()

我不明白为什么在 kivy 语言中我应该使用括号而不是在 python 中。你能帮帮我吗?

【问题讨论】:

因为这两种语言的设计者就是这样设计它们的。 出于同样的原因,您必须使用: 而不是=;它们是不同的语言,具有不同的语法。你不妨问“为什么我必须在法语和英语中使用不同的词?” @jonrsharpe 这不太行。 on_press: 之后的部分是 Python 代码的片段,或者至少看起来是。保持语言类比:为什么法语借词的拼写与源词不同? 首先,这是给programmers.stackexchange.com 的一个问题。此外,简短的回答是,python 通过在没有调用运算符() 的情况下给出名称来引用可调用对象,这将返回调用对象的结果。显然,Kivy 根据上下文区分这两者。 其中一些 cmets 指出了语言差异,但重要的是 'Kivy' 在这里没有做任何特别的事情 - 这两件事都是纯 python,只是一个涉及传递方法( popup.dismiss) 稍后调用,而另一个涉及直接运行一行 python 代码 (root.dismiss())。后者虽然是kivy语言,但是这里没有区别,全部写在python文件比如on_press方法里也一样。 【参考方案1】:

虽然两者都实现了相同的目标,但 kv 和 Python 以不同的方式完成它们。

在 Python 中,当您执行 Button(text='anytext', on_press=popup.dismiss) 时,您实际上是在告诉 kivy:当按下时,调用 popup.dismiss 方法。也就是说,你向它传递了一个对象(在这种情况下是一个类方法),kivy 将在正确的时间调用它。

在 kv 中,当你执行 on_press: root.dismiss() 时,当按下事件发生时,kivy 将执行冒号后面的任何文本(在这种情况下为 root.dismiss())。因此,您需要在该文本中自己拨打root.dismiss()

【讨论】:

【参考方案2】:

细说一下:当你把回调代码放在 kv 中时,就像是在做一个 lambda。

所以这个kv代码:

on_press: popup.dismiss()

等价于以下 Python 代码:

Button(text='anytext', on_press=lambda *args: popup.dismiss())

on_press=popup.dismiss 起作用的唯一原因是Popup.dismiss() 吞下了额外的参数(Button 实例作为第一个参数传递)。所以在这种情况下,两者似乎是等价的,但通常不是。

以这段代码为例:

def callback():
    pass

button = Button(on_press=callback)

Button 被按下时,它会调用callback(self) - 这将引发异常,因为callback 不接受任何参数。

相比之下,这段代码的工作方式类似于dismiss

def callback(*args, **kwargs):
    pass

button = Button(on_press=callback)

当然还有kv:

on_press: callback()

...无论您使用哪个 callback 定义,它都有效。

【讨论】:

以上是关于为啥 Kivy 需要括号,而 Python 不需要括号?的主要内容,如果未能解决你的问题,请参考以下文章

为啥我需要创建 Line 的新实例,而不是在 Kivy 中简单地更新或添加和删除它

为啥我需要创建 Line 的新实例,而不是在 Kivy 中简单地更新或添加和删除它

为啥 Kivy 使用浮点数而不是整数?

为啥没有构造函数参数的类需要括号

为啥在 Kivy 中创建方法时需要“实例”变量?

为啥我的 kivy 程序没有从另一个类调用函数?