带括号和不带括号的函数调用

时间:2021-03-20 11:20:17

标签: python function tkinter lambda parameters

我开始学习 Tkinter 并遇到了这段用于 2 数计算器的代码。在自己尝试之后,我注意到了一些事情,即使在阅读了文档并使用控制台之后,它也让我感到困惑。

button_equalbutton_clear 不要在 command 参数下使用括号。为什么会这样,如果我添加它们,为什么它不起作用。 从我读到的我可以看到,当调用它括号时,它会调用并执行该函数。但是当调用没有括号时,它传递了一个引用?这对我来说仍然很模糊,如果有人能帮我把它简单化,我会很高兴的。也许举个例子:)

import tkinter as tk

root = tk.Tk()
root.title("Mathz")

### Variables ##########################################################################
buttonWidth = 30
buttonHeight = 20
global f_number


### FUNCTIONS ##########################################################################################
def button_click(number):
    current = e.get()
    e.delete(0, tk.END)
    e.insert(0, str(current) + str(number))


def button_add():
    first_number = e.get()
    global f_num
    f_num = int(first_number)
    e.delete(0, tk.END)


def button_equal():
    second_number = e.get()
    e.delete(0, tk.END)
    e.insert(0, f_num + int(second_number))


def button_clear():
    e.delete(0, tk.END)


### Defining Widgets ###############################################################################

e = tk.Entry(root, width=35, borderwidth=5, bg='lightgrey')
e.grid(row=0, column=0, columnspan=3)

button_1 = tk.Button(root, text='1', padx=buttonWidth, pady=buttonHeight, command=lambda: button_click(1))
button_2 = tk.Button(root, text='2', padx=buttonWidth, pady=buttonHeight, command=lambda: button_click(2))
button_3 = tk.Button(root, text='3', padx=buttonWidth, pady=buttonHeight, command=lambda: button_click(3))
button_4 = tk.Button(root, text='4', padx=buttonWidth, pady=buttonHeight, command=lambda: button_click(4))
button_5 = tk.Button(root, text='5', padx=buttonWidth, pady=buttonHeight, command=lambda: button_click(5))
button_6 = tk.Button(root, text='6', padx=buttonWidth, pady=buttonHeight, command=lambda: button_click(6))
button_7 = tk.Button(root, text='7', padx=buttonWidth, pady=buttonHeight, command=lambda: button_click(7))
button_8 = tk.Button(root, text='8', padx=buttonWidth, pady=buttonHeight, command=lambda: button_click(8))
button_9 = tk.Button(root, text='9', padx=buttonWidth, pady=buttonHeight, command=lambda: button_click(9))
button_0 = tk.Button(root, text='0', padx=buttonWidth, pady=buttonHeight, command=lambda: button_click(0))
button_plus = tk.Button(root, text='+', padx=buttonWidth - 1, pady=buttonHeight, command=lambda: button_add())
button_equal = tk.Button(root, text='=', padx=69, pady=buttonHeight, command=button_equal)
button_clear = tk.Button(root, text='Clear', padx=buttonWidth * 2, pady=buttonHeight, command=button_clear)

### Positioning Widgets ######################################################################################

button_1.grid(row=3, column=0)
button_2.grid(row=3, column=1)
button_3.grid(row=3, column=2)

button_4.grid(row=2, column=0)
button_5.grid(row=2, column=1)
button_6.grid(row=2, column=2)

button_7.grid(row=1, column=0)
button_8.grid(row=1, column=1)
button_9.grid(row=1, column=2)

button_0.grid(row=4, column=0)
button_clear.grid(row=4, column=1, columnspan=2)
button_equal.grid(row=5, column=1, columnspan=2)

button_plus.grid(row=5, column=0)

root.mainloop()

2 个答案:

答案 0 :(得分:2)

开始和了解这里发生的事情的最佳方式,我想是指出 tkinter 基于另一种编程语言,称为 tcl。 tkinter 是 tcl 中的 GUI 包,并通过包装器与 python 一起使用。因此,您需要稍微了解一下这两种语言才能了解正在发生的事情。

首先考虑这里的代码:

import tkinter as tk

def func():
    print('func is running')

root = tk.Tk()
b = tk.Button(root, text='exampel', command=func)
b.pack()
root.mainloop()

这是一个创建窗口的标准脚本,带有一个可以执行的按钮。 如果您在 root.mainloop() 之前添加一行代码,其形式如下:

print(func)

为我输出

<function func at 0x03D803D8>

这是存储在这个变量中的信息。它让你知道这是一个名为 funcfunction 对象,你会在 在 0x03D803D8 找到它。 此信息将由 tkinter 的包装器解释并将其转换为一串 tcl 代码。您可以通过这一行证明这一点:

print(b['command'])

输出

31262160func

这段代码包含类似python的类似信息。它包含关于这是一个函数以及在哪里可以找到它的信息。我深入地写了 Functions & lambda 如何在 python 中工作。但是对于这个问题,您需要知道的只是语法 () 执行该函数。执行后它返回到它被调用的那个点。在 python 中,你可以返回诸如字符串;整数;对象;等 将在调用函数的地方就位。


所以让我们在这里考虑一下这段代码:

import tkinter as tk

def func():
    print('func is running')

def get_func():
    return func

root = tk.Tk()
b = tk.Button(root, text='exampel', command=get_func())
b.pack()

root.mainloop()

所以这里发生的事情是无稽之谈,但向您展示了它是如何进行的。除了我们首先考虑的代码之外,我们将通过 command 的可选参数与新函数 get_func() 交换的函数。就像我解释的那样,该函数将由语法 () 执行,并使用语句 return funcfnction 对象 放在我们调用它的地方。所以代码在运行后看起来更像这样:

b = tk.Button(root, text='exampel', command=func)

在此处添加这段代码,位于 root.mainloop() 上方的某个位置以获取有关此处发生的情况的更多信息:

print(get_func)
print(get_func())
print('next')
print(func)
print(func())

输出

<function get_func at 0x02600390> #get_func function
<function func at 0x046303D8> #returned by get_function
next
<function func at 0x046303D8> #func function
func is running 
None #returned by func

如果还有问题,请告诉我。


更新

<块引用>

我仍然感到困惑,因为您通过以下方式调用了 func 而不是 func() 命令。

func 与我已经解释过的信息一起存储。括号就像运行那个函数的同义词。您通常想要做的是存储该函数并在 Click_Event 发生时调用它,而不是在构建 Button 时运行该函数。所以想象一下,每次 Click_Event 发生时,() 都会添加到存储的函数中。

我希望你accept回答这个问题。因为更多的问题会包括更多关于 Class;Eventloop 的信息。

答案 1 :(得分:0)

当您使用参数:command=button_equal 时,您是在告诉按钮要调用哪个函数。

当按钮本身被点击时,它就会知道要调用哪个函数,并且它会在那个时候而不是迟早调用它。

相关问题