在for循环中定义一个函数

时间:2017-03-04 00:06:28

标签: python python-3.x tkinter

我是相对Python和tkinter的新手。我正在尝试为列表中的每个项目创建一个按钮。

from tkinter import *

x = ['d', 'f']

class GUI:

    def __init__(self, master):

        self.master = master
        master.title("window")

        self.label = Label(master, text="Window")
        self.label.grid(columnspan=5, sticky=W+E)

        self.close_button = Button(master, text="Close", command=master.destroy)
        self.close_button.grid(columnspan=5, sticky=W+E)

        for s in x:
            self.s_button = Button(master, text=s, command=self.s)
            self.s_button.grid(columnspan=5, sticky=W+E)

    for a in x:
        def a(self):
            print (a)     

root = Tk()
gui = GUI(root)
root.mainloop()

每当我运行代码时,都会收到错误AttributeError: 'GUI' object has no attribute 's'

1 个答案:

答案 0 :(得分:1)

第一个错误:command=self.s查找名为" s"的属性。如果要查找名称为s变量内容的属性,则应编写command=getattr(self, s)

第二个错误:def a(self)定义了一个名为" a"的类方法。如果要以编程方式生成命名方法,可以在之后创建类,如下所示:

for a in x:
    def fun(self):
        print (a)
    setattr(GUI, a, fun)

编辑:这仍然是错误的,因为两个函数都使用相同的变量a

无论如何,以这种方式生成方法看起来很奇怪,我宁愿使用单个方法将内容作为参数打印,例如:

from tkinter import *

x = ['d', 'f']

class GUI:
    def __init__(self, master):
        self.master = master
        master.title("window")

        self.label = Label(master, text="Window")
        self.label.grid(columnspan=5, sticky=W+E)

        self.close_button = Button(master, text="Close", command=master.destroy)
        self.close_button.grid(columnspan=5, sticky=W+E)

        for s in x:
            self.s_button = Button(master, text=s, command=(lambda: self.print_(s)))
            self.s_button.grid(columnspan=5, sticky=W+E)

    def print_(self, a):
        print (a)

root = Tk()
gui = GUI(root)
root.mainloop()

编辑:由于for循环不创建新范围,因此共享的s变量仍然是错误的。只有函数才能创建新的范围。这是一些有效的代码:

from tkinter import *

x = ['d', 'f']

class GUI:
    def __init__(self, master):
        self.master = master
        master.title("window")

        self.label = Label(master, text="Window")
        self.label.grid(columnspan=5, sticky=W+E)

        self.close_button = Button(master, text="Close", command=master.destroy)
        self.close_button.grid(columnspan=5, sticky=W+E)

        for s in x:
            self.s_button = Button(master, text=s, command=self.make_printer(s))
            self.s_button.grid(columnspan=5, sticky=W+E)

    def make_printer(self, a):
        def fun():
            print (a)
        return fun

root = Tk()
gui = GUI(root)
root.mainloop()