为啥 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 中简单地更新或添加和删除它