使用 turtle 包,是否可以创建一个需要参数的函数? (然后将其用于 .onkeypress 方法)

Using the turtle package, is it possible to create a function asking for an argument? (And then use it for the .onkeypress method)

我在 Python 上尝试使用 turtle 包制作 Pong 项目。

我知道如何使代码工作(使用 4 个不带参数的不同函数,每个桨和方向),但我的问题是我是否以及如何使用这个想法来实现。

这是我尝试使用的代码:

def move_paddle_up(paddle):
        y = paddle.ycor()
        y += 20
        paddle.sety(y)
    
def move_paddle_down(paddle):
        y = paddle.ycor()
        y -= 20
        paddle.sety(y)

#Keyboard binding movement
screen.listen()
screen.onkeypress(move_paddle_up(left_pad), "w")
screen.onkeypress(move_paddle_down(left_pad), "s")
screen.onkeypress(move_paddle_up(right_pad), "Up")
screen.onkeypress(move_paddle_down(right_pad), "Down")

当屏幕启动时,如果我按下关联的键,桨不会移动。

4个不同函数的使用方式,就可以了

只是我很好奇我应该如何调用或定义这样一个函数中的参数。

onkeypress 方法不允许传递带参数的函数,但是您可以在这种情况下使用 functools.partial

您可以创建一个函数来处理所有类型的键盘按下,并将该函数作为 partial function.
传递 让我们先创建该函数:

def move_paddle(paddle, key_pressed):

    def move_paddle_up(paddle):
            y = paddle.ycor()
            y += 20
            paddle.sety(y)
        
    def move_paddle_down(paddle):
            y = paddle.ycor()
            y -= 20
            paddle.sety(y)

    if paddle == left_pad:
       if key_pressed == "w":
          move_paddle_up(paddle)
       elif key_pressed == "s":
          move_paddle_down(paddle)

    elif paddle == right_pad:
       if key_pressed == "Up":
          move_paddle_up(paddle)
       elif key_pressed == "Down":
          move_paddle_down(paddle)

现在我们可以将这个函数与functools.partial一起使用:

import functools
[...]
screen.onkeypress(functools.partial(move_paddle,[left_pad,"w"]), key="w")
screen.onkeypress(functools.partial(move_paddle,[left_pad,"s"]), key="s")
screen.onkeypress(functools.partial(move_paddle,[right_pad,"Up"]), key="Up")
screen.onkeypress(functools.partial(move_paddle,[right_pad,"Down"]), key="Down")

functools.partial 的工作方式:
它需要一个 function 和一些 arguments (*args,它实际上是一个未打包的列表),然后创建一个新函数,它是获取这些 args 作为输入的前一个函数:

def partial(func, /, *args, **keywords):
    def newfunc(*fargs, **fkeywords):
        newkeywords = {**keywords, **fkeywords}
        return func(*args, *fargs, **newkeywords)
    newfunc.func = func
    newfunc.args = args
    newfunc.keywords = keywords
    return newfunc

I see then that is it quite more work than just creating 4 functions.

我想你听错了带回家的信息。 @BehdadAbdollahiMoghadam 对 functools.partial() 的使用恰到好处,但我们可以以更少的开销将其融入您现有的代码:

from functools import partial

# ...

def move_paddle_up(paddle):
    paddle.sety(paddle.ycor() + 20)

def move_paddle_down(paddle):
    paddle.sety(paddle.ycor() - 20)

# Keyboard binding movement
screen.onkeypress(partial(move_paddle_up, left_pad), "w")
screen.onkeypress(partial(move_paddle_down, left_pad), "s")
screen.onkeypress(partial(move_paddle_up, right_pad), "Up")
screen.onkeypress(partial(move_paddle_down, right_pad), "Down")
screen.listen()

# ...