Python - 如果我删除Lambda,那么app是未定义的?

时间:2015-10-01 16:09:57

标签: python lambda tkinter

此代码工作正常。

CalculateButton = tk.Button(self.root, text="Calculate", command=lambda: calc.GrandTotal()).grid(row=6, column=0, sticky=tk.W+tk.E)

但是这段代码会导致错误:" NameError:全局名称' app'未定义"

CalculateButton = tk.Button(self.root, text="Calculate", command=calc.GrandTotal()).grid(row=6, column=0, sticky=tk.W+tk.E)

那么为什么删除Lambda会导致错误?

源代码本身是:

    # -*- coding: cp1252 -*-
import Tkinter as tk
import tkMessageBox

# Classes
class Application(tk.Frame):
    def __init__(self):

        # Create G.U.I. Framework
        self.root = tk.Tk()
        tk.Frame.__init__(self)
        self.root.title("Job Estimator")
        self.root.geometry("290x152")
        self.root.resizable(0,0)

        # Create G.U.I. Widgets
        tk.Label(self.root, text="Labour:   "   + unichr(163) + "40.00 x Hours")  .grid(row=0, column=0, sticky=tk.W)
        tk.Label(self.root, text="Travel:     " + unichr(163) + "1.00   x Miles") .grid(row=1, column=0, sticky=tk.W)
        tk.Label(self.root, text="Plastic:    " + unichr(163) + "2.00   x Metres").grid(row=2, column=0, sticky=tk.W)
        tk.Label(self.root, text="Copper:  "    + unichr(163) + "3.00   x Metres").grid(row=3, column=0, sticky=tk.W)
        tk.Label(self.root, text="Chrome: "     + unichr(163) + "4.00  x Metres") .grid(row=4, column=0, sticky=tk.W)
        tk.Label(self.root, text="Total: "      + unichr(163))                    .grid(row=5, column=0, sticky=tk.W)

        self.totalLabel = tk.Label(self.root, text="0.00")
        self.totalLabel.grid(row=5, column=0, sticky=tk.W, padx=42, pady=0)

        self.LabourInput = tk.Entry(self.root)
        self.LabourInput.grid(row=0, column=1)
        self.LabourInput.insert(0, "0")

        self.TravelInput = tk.Entry(self.root)
        self.TravelInput.grid(row=1, column=1)
        self.TravelInput.insert(0, "0")

        self.PlasticInput = tk.Entry(self.root)
        self.PlasticInput.grid(row=2, column=1)
        self.PlasticInput.insert(0, "0")

        self.CopperInput = tk.Entry(self.root)        
        self.CopperInput.grid(row=3, column=1)
        self.CopperInput.insert(0, "0")

        self.ChromeInput = tk.Entry(self.root)        
        self.ChromeInput.grid(row=4, column=1)     
        self.ChromeInput.insert(0, "0")

        CalculateButton = tk.Button(self.root, text="Calculate", command=calc.GrandTotal()).grid(row=6, column=0, sticky=tk.W+tk.E)

class Calculator():
    def __init__(self):
        pass

    def Multiply(self, number, rate):
        try:
            NumFloat = float(number)
            RateFloat = float(rate)
            return NumFloat * RateFloat
        except (ValueError):
            raise tkMessageBox.showerror("Error", "One or more text fields contains non-numerical characters.")

    def GrandTotal(self): # Adds each entry field to produce and return a grand total. 

        # Set Variables
        self.LabourTotal   = self.Multiply(app.LabourInput. get(), 40)
        self.TravelTotal   = self.Multiply(app.TravelInput. get(), 1)
        self.PlasticTotal  = self.Multiply(app.PlasticInput.get(), 2)
        self.CopperTotal   = self.Multiply(app.CopperInput. get(), 3)
        self.ChromeTotal   = self.Multiply(app.ChromeInput. get(), 4)

        self.CompleteTotal = self.LabourTotal + self.TravelTotal + self.PlasticTotal + self.CopperTotal + self.ChromeTotal

        return app.totalLabel.config(text=self.CompleteTotal) # Return the total value.

calc = Calculator()
app = Application()
app.mainloop()

有什么想法吗?

2 个答案:

答案 0 :(得分:1)

在创建app实例之后才定义

Application(),这意味着Application.__init__必须先完成

删除lambda后,您直接调用calc.GrandTotal()方法,该方法依赖于已存在的app。它没有,因为Application.__init__还没有完成。

然而,command参数的重点是传递稍后将被称为的内容。这就是lambda工作的原因,当按下计算按钮时,它会生成一个稍后调用calc.GrantTotal()的函数。通过直接调用它可以使这条正常路径短路。

calc.GrantTotal

请注意,我在单独的表达式中调用了()方法。 CalculateButton = tk.Button( self.root, text="Calculate", command=calc.GrandTotal) CalculateButton.grid(row=6, column=0, sticky=tk.W+tk.E) 返回Button.grid();将返回值存储在变量中没有意义。改为存储Button.grid()返回值。

答案 1 :(得分:0)

lambda用于创建一个函数,当被调用时(即,当您单击按钮时),将调用calc.GrandTotal。没有它,您将立即调用GrantTotal的返回值指定为回调。