在 python 中,将函数用作 class 的属性的正确语法是什么?

In python, what is the proper syntax for using a function as an attribute of a class?

我是编程新手,我正在尝试通过在 pygame 中制作一个简单的游戏来学习。我将使用很多可点击的按钮,所以我决定为它们制作一个 class。作为属性,我希望它们有一个 pygame.Rect 对象(告诉我将它们放在屏幕上的什么位置)、一个 pygame.Surface 对象(告诉我它应该是什么样子)和一个函数在下面的代码中调用 'action',每当单击按钮时都会调用它。这是我的尝试:

class Button:
    def __init__(self, rect, surf, action = None):
        self.rect = rect
        self.surf = surf
        self.action = action
        
    def draw(self, surf):
        surf.blit(self.surf, self.rect)

    def click(self, event):
        if event.type == pygame.MOUSEBUTTONUP:
            mouse_pos = pygame.mouse.get_pos()
            if self.rect.collidepoint(mouse_pos) and self.action != None:
                self.action()

例如,如果我想制作一个将某个全局变量“money”增加 1 的按钮,那么我可以这样做

def change_money():
    global money
    money = money + 1

#some code here to define button_rect, button_surf

button = Button(button_rect, button_surf, change_money)

这样可以完成工作,但它非常不令人满意,因为如果我想制作一个新按钮将钱增加 2,我将不得不定义一个新函数 change_money_2() 然后执行 button2 = Button(button2_rect, button2_surf, change_money_2)

我尝试了天真的方法:

def change_money(delta):
    global money
    money = money + delta

button2 = Button(button_rect, button_surf, change_money(2))

但这不起作用。

问题 1将函数作为 classes 的属性传递的正确语法是什么;特别是,如果函数有输入,你会怎么做?

问题 2 理想情况下,我希望不必为简单操作定义新函数 money = money + 1。有没有一种方法可以将这样的函数作为 class 的属性传递而不必给它命名? (例如,类似 button = Button(button_rect, button_surf, [money -> money + 1]).

编辑 1: 感谢您提出使用 lambda 函数的建议;我不知道这些。有没有办法让 lambda 函数接受全局变量?天真的 lambda global money : money = money + 2lambda : money = money + 2 似乎不起作用。我的直觉(基于 Rabbid76 的 reference)是这些 lambda 函数非常适合使用 return 语句“模仿”函数,但是如果我想模仿没有 return 的函数怎么办?声明,例如 change_money()?

使用 lambda:

button2 = Button(button_rect, button_surf, change_money(2))

button2 = Button(button_rect, button_surf, lambda: change_money(2))

Is there a way of having a lambda function take a global variable?

不,您不能在 lambda 表达式中使用 global statement。 lambda 没有语句列表,它是单个表达式。