Binding functions to buttons created in a loop in

2020-05-06 08:09发布

I wrote a for loop to create buttons according to the number of sheets in an excel workbook. However, I'm having a hard time binding functions that print the data on each sheet. Can anyone help? Thanks. Here's what I have done

wb = xlrd.open_workbook('file_path.xlsx')
        sheetnames = wb.sheet_names()
        num_sheets = len(sheetnames)

        def load_sheet():
        for d in range(0, num_sheets):
            print(sheetnames[d])

        for i in range(0, num_sheets):
            an_sheet = ttk.Button(self, text = "%s" % sheetnames[i], 
                                  command= lambda : load_data)
            an_sheet.grid(row = 1, column = i+1, sticky='w', pady = 10, padx = 10)

1条回答
可以哭但决不认输i
2楼-- · 2020-05-06 08:36

It's a common beginner's issue if you are using lambda in a for loop because beginners don't realize that lambda is late-binding. In other words it always uses the last value of "i", not the value of "i" when the command argument was set. In this case you need to use functools.partial instead:

from functools import partial
# ...
for i in range(0, num_sheets):
    an_sheet = ttk.Button(self, text = "%s" % sheetnames[i], command=partial(function, i))
    an_sheet.grid(row = 1, column = i+1, sticky='w', pady = 10, padx = 10)
查看更多
登录 后发表回答