【问题标题】:Why is my calculator program not working - Python?为什么我的计算器程序不起作用 - Python?
【发布时间】:2014-08-12 20:46:32
【问题描述】:

我正在编写一个计算器程序,但遇到了一个小问题。 每当我按下其中一个按钮时,它每次都会将数字增加 9,即使它应该是 i(来自 for 循环)。 请问有人能告诉我为什么总是9吗?

代码 -

import tkinter

plus = True

numbers = 0

def main():

    def numButton(i):
        global numbers
        if plus == False:
            numbers-=i
        else:
            numbers+=i
    def quitHandler():
        root.destroy()
    def entryHandler():
        global numbers
        numbers+=int(text.get())
        text.set("")
    def printHandler():
        text2.set(numbers)
    def restartHandler():
        global numbers
        root.destroy()
        plus = True
        numbers = 0
        main()
    def plusHandler():
        global plus
        plus = True
    def minusHandler():
        global plus
        plus = False

    root = tkinter.Tk()
    frame = tkinter.Frame(root).pack(side=tkinter.TOP)

    text = tkinter.IntVar()
    text2 = tkinter.IntVar()
    text.set("")
    text2.set("")

    tkinter.Entry(frame,bd =8,textvariable=text).pack()

    tkinter.Button(frame,padx=8,pady=8,bd=8,text="Enter",command=entryHandler).pack()
    tkinter.Button(frame,padx=8,pady=8,bd=8,text="Quit",command=quitHandler).pack(side=tkinter.RIGHT)
    tkinter.Button(frame,padx=8,pady=8,bd=8,text="Restart",command=restartHandler).pack(side=tkinter.RIGHT)
    tkinter.Button(frame,padx=8,pady=8,bd=8,text="Print",command=printHandler).pack(side=tkinter.LEFT)

    tkinter.Entry(frame,bd =8,textvariable=text2).pack(side=tkinter.LEFT)

    _padx = 16
    _pady = 16
    _bd = 8

    for i in range (1,10):
        tkinter.Button(frame, padx = _padx, pady = _pady, bd = _bd, text = str(i), command = lambda: numButton(i)).pack(side = tkinter.LEFT)

    tkinter.Button(frame,padx=8,pady=8,bd=8,text="+",command=plusHandler).pack(side=tkinter.LEFT)
    tkinter.Button(frame,padx=8,pady=8,bd=8,text="-",command=minusHandler).pack(side=tkinter.LEFT)

main()

谁能告诉我如何将所有这些内容放在本网站的代码中,我无法弄清楚以及该网站的帮助显示我无法正常工作的方式(或请管理员修复)。


好的,谢谢大家,有人给我发了电子邮件解决方案:

    tkinter.Button(frame, padx = _padx, pady = _pady, bd = _bd, text = str(i), command = lambda i=i: numButton(i)).pack(side = tkinter.LEFT)

必须在 lamda 之后添加 i=i。 有人可以向我解释一下 i=i 的作用吗?

谢谢

【问题讨论】:

    标签: python user-interface python-3.x tkinter calculator


    【解决方案1】:
    command = lambda: numButton(i)
    

    这不会在创建 lambda 时查找 i 的值并将其插入到函数中。当调用 lambda 时,然后它会查找 i。到那时,i 始终是 9

    有几种方法可以解决这个问题,所有方法都集中在确保i 被查找command 的创建时间而不是执行时间。我会使用functools.partial,这是一种旨在将函数与参数相关联的工具:

    from functools import partial
    ...
    command=partial(numButton, i)
    

    您也可以使用默认参数,这有点笨拙:

    command=lambda i=i: numButton(i)
    

    或者写一个工厂函数:

    def closure_maker(i):
        def closure():
            numButton(i)
        return closure
    ...
    command=closure_maker(i)
    

    【讨论】:

      【解决方案2】:

      用于命令的 lambda 函数引用变量 i

      for i in range (1,10):
          tkinter.Button(frame, padx = _padx, pady = _pady, bd = _bd, text = str(i),
                  command = lambda: numButton(i)).pack(side = tkinter.LEFT)
      

      当命令执行并且 lambda 函数运行时,它会选择按钮编号i。但当时执行 lambda 函数时,i 包含值 9(即在创建按钮的 for 循环完成后,i 的值结束。

      要解决此问题,请确保 lambda 函数不共享同一个全局变量。一种方法是使用创建新本地范围的函数:

      def numCommand(x):
          return (lambda: numButton(x))
      
      for i in range (1,10):
          tkinter.Button(frame, padx = _padx, pady = _pady, bd = _bd, text = str(i),
                  command = numCommand(i)).pack(side = tkinter.LEFT)
      

      这里每个 lambda 函数都通过其 numCommand() 调用引用其自己的 x 变量。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2022-11-14
        • 1970-01-01
        • 2017-03-12
        • 1970-01-01
        • 2020-12-03
        • 1970-01-01
        • 2023-01-18
        相关资源
        最近更新 更多