【发布时间】:2019-11-24 07:08:53
【问题描述】:
在 Python turtle 中,如果我想传递与事件系统指定的不同的事件处理程序参数,我可以使用 lambda 来弥补差异:
from turtle import Screen, Turtle
from functools import partial
def change_color(color, x=None, y=None):
screen.bgcolor(color)
screen = Screen()
screen.onclick(lambda x, y: change_color('blue'))
screen.mainloop()
或者我可以使用从 functools 导入的 partial 函数将 lambda 替换为:
screen.onclick(partial(change_color, 'blue'))
而且效果很好。回到我们原来的程序,我们可以用ontimer() 事件替换我们的onclick() 事件,更新我们的lambda,一切正常很好:
screen.ontimer(lambda: change_color('blue'), 1000)
但是,当我们将 lambda 替换为 partial 时:
screen.ontimer(partial(change_color, 'blue'), 1000)
它失败立即(不是在计时器触发时):
Traceback (most recent call last):
File "test.py", line 9, in <module>
screen.ontimer(partial(change_color, 'blue'), 1000)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/turtle.py", line 1459, in ontimer
self._ontimer(fun, t)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/turtle.py", line 718, in _ontimer
self.cv.after(t, fun)
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/__init__.py", line 755, in after
callit.__name__ = func.__name__
AttributeError: 'functools.partial' object has no attribute '__name__'
>
由于 turtle 位于 tkinter 之上,并且 tkinter 涉及堆栈跟踪,因此我们可以再往下一层:
import tkinter as tk
from functools import partial
def change_color(color):
root.configure(bg=color)
root = tk.Tk()
root.after(1000, change_color, 'blue')
root.mainloop()
哪个工作很好。我们也可以这样做:
root.after(1000, lambda: change_color('blue'))
哪个工作很好。但是当我们这样做时:
root.after(1000, partial(change_color, 'blue'))
立即再次失败:
Traceback (most recent call last):
File "test.py", line 9, in <module>
root.after(1000, partial(change_color, 'blue'))
File "/Library/Frameworks/Python.framework/Versions/3.7/lib/python3.7/tkinter/__init__.py", line 755, in after
callit.__name__ = func.__name__
AttributeError: 'functools.partial' object has no attribute '__name__'
>
partial 的 functools 文档声明其返回值的行为类似于 函数,但显然它是不同的,如果不是缺少的话,不知何故。这是为什么?为什么 tkinter/turtle 接受 partial 函数作为 click 事件处理程序,而不是作为 timer 事件处理程序?
【问题讨论】:
标签: python tkinter event-handling turtle-graphics