您总是可以将两个列表或两个元组合并为一个,只需+
:
can.coords(oval1, *(moveLeft() + addThirty(moveLeft())))
即使你有不同类型的序列(甚至迭代器),你也可以随时转换它们:
can.coords(oval1, *(moveLeft() + tuple(addThirty(moveLeft())))))
然而,你真的应该退后一步,问问为什么这首先需要成为一行。它从屏幕的右边缘滚动,它需要足够复杂的括号,你必须考虑它才能理解它,等等。为什么不这样做:
top, left = moveLeft()
bottom, right = addThirty(moveLeft())
can.coords(oval1, top, left, bottom, right)
在评论中,你说:
我不能这样做,因为我希望每次按下按钮时坐标都会改变。所以按钮需要: 执行这两个函数来修改坐标并一次性将它们传递给can.coords()。
仅仅把它放在一行中并不能做到这一点,甚至有助于使它更容易。您编写它的方式是调用can.coords
一次,并将结果返回值作为命令传递。那不是你想要的。你需要传递的是一个完成所有这些事情的函数。
这意味着你肯定想把它分成多行。例如:
def update_coords():
top, left = moveLeft()
bottom, right = addThirty(moveLeft())
can.coords(oval1, top, left, bottom, right)
Button(wind, text = 'Left', command=update_coords)
因为将它放在一行中的唯一方法是使用等效的lambda
or partial
,这将比调用更不可读;就像是:
Button(wind, text = 'Left', command=lambda: can.coords(oval1, *(moveLeft() + addThirty(moveLeft()))))
为了解释传递函数和调用函数并传递其返回值之间的区别,让我们举一个更简单的例子:
>>> def foo():
... return 2
>>> print(foo)
<function foo at 0x12345678>
>>> print(foo())
2
在这里,应该很清楚区别是什么。foo
是一个表达式,其值为函数foo
本身。Butfoo()
是一个表达式,其值通过foo
不带参数的调用确定,然后使用返回的任何内容(在本例中为2
)。
如果我们让它更复杂一点,它也没有什么不同:
>>> def bar(x, y):
... return x+y
>>> print(bar)
<function bar at 0x12345680>
>>> print(bar(2, 3))
6
所以,很明显你可以如何传递bar
它自己,或者你如何传递6
你从bar(2, 3)
......但是如果你想传递一个可以不带参数调用的函数并返回与返回相同的东西bar(2, 3)
怎么办?好吧,你没有这样的东西;你必须创建它。
您可以通过两种方式执行此操作: 创建一个新函数:
>>> def new_function():
... return bar(2, 3)
…或部分评估功能:
>>> new_function = partial(bar, 2, 3)
您的案例增加了一些额外的皱纹:您从绑定方法而不是函数开始,您需要确保每次运行新函数时都对参数进行评估(因为每次调用moveLeft()
两次而不是每次调用一次和每次都打电话一样重要can.coords
),而且你会遇到一堆复杂的论点。但这些皱纹都不会让事情变得更难。你只需要看过去:
>>> def new_function():
... can.coords(oval1, *(moveLeft() + addThirty(moveLeft())))
(partial 会更难编写,因为您必须将一系列函数组合在一起才能获取参数,您也需要对其进行 partial ......但是当 partial 在 Python 中不是微不足道的时候,不要尝试算了,写一个显式函数就行了。)