Mic wrote: > >> >from functools import partial > >>I use this kind of explicit import for a few names that I use frequently, >>namely defaultdict, contextmanager, everything from itertools... >>I think of these as my personal extended set of builtins ;) > >>As to the actual partial() function, you probably don't see it a lot >>because >>it has been in the standard library for only three years. The older idiom >>for making a function that calls another function with a fixed argument is > > command = lambda button=button: button_clicked(button) > > Alright! What is a fixed argument?
Suppose you have a function add() that calculates the sum of two values >>> def add(a, b): ... return a + b ... >>> add(1, 2) 3 If you want another function that takes one argument and adds 2 to that argument you can either start from scratch >>> def plus_two(b): ... return 2 + b ... >>> plus_two(7) 9 or build on your earlier work >>> from functools import partial >>> plus_two = partial(add, 2) >>> plus_two(3) 5 The effect of wrapping add into partial here is that every time you call plus_two(x) it will in turn call add(2, x). As the first argument is always the same I called it "fixed", but it's not a terminus technicus. >>You can iterate over (row, column) pairs instead of the dummy _ variable: > >>def create_widgets(self): > >for row, column in [(0, 0), (1, 1), (2, 2), (3, 0)]: > >button = tk.Button(self) > >command = partial(button_clicked, button) > >button["command"] = command > >button.grid(row=row, column=column) > >command() > > Very nice! I didn't know that it was possible. This saves me a lot of > space. Am I, as a beginner, supposed to know this? You may read it up somewhere or be shown on a mailinglist ;) > Say that when button one is pressed I want a text file to be created. The > text in the > file should be the same number as the button I pressed. So if I press > button one, once, > it should create a text file with the name button_1. The text in the file > should also be "button_1". > > If the button is pressed again, it should remove the file. Is this > possible to do without > any trouble? > > So if the second button is pressed , it should create a text file with the > name button_2 > and the text in it should be button_2. If the button is pressed once > again, it is supposed to > delete that file it created. > I also have one last question. > How do I make the first button that is created to be named > 1, the second to be created 2, the third 3 and so on? Here's a modified script: import tkinter as tk from functools import partial def button_clicked(button): if button["bg"] == "green": button["bg"] = "red" print("deleting file", button.filename) else: button["bg"] = "green" print("creating file", button.filename) class Window(tk.Frame): def __init__(self, master): super (Window, self).__init__(master) self.grid() self.create_widgets() def create_widgets(self): for index in range(20): button = tk.Button(self, text="Button {}".format(index+1), bg="red") button.filename = "button{}.txt".format(index+1) command = partial(button_clicked, button) button["command"] = command row, column = divmod(index, 4) button.grid(row=row, column=column) root = tk.Tk() root.title("Test") app = Window(root) root.mainloop() I hope you can infer answers to your questions from the above... To be honest, we've reached the point where I would switch to a tkinter.Button subclass: import tkinter as tk FREE = "green" OCCUPIED = "red" class SeatButton(tk.Button): def __init__(self, master, index): text = "Button {}".format(index+1) super(SeatButton, self).__init__(master, text=text, bg=FREE, command=self.clicked) self.filename = "button{}.txt".format(index+1) self.occupied = False def clicked(self): self.occupied = not self.occupied if self.occupied: self["bg"] = OCCUPIED print("creating file", self.filename) else: self["bg"] = FREE print("deleting file", self.filename) class Window(tk.Frame): def __init__(self, master): super (Window, self).__init__(master) self.grid() self.create_widgets() def create_widgets(self): for index in range(20): button = SeatButton(self, index) row, column = divmod(index, 4) button.grid(row=row, column=column) root = tk.Tk() root.title("Test") app = Window(root) root.mainloop() Too bad that now you've understood what partial() does it's gone... > Why is it not recommended to to mix the styles if you put the respective > imports at the > beginning of the module? Consistency. Either call the button tk.Button or Button. _______________________________________________ Tutor maillist - Tutor@python.org To unsubscribe or change subscription options: http://mail.python.org/mailman/listinfo/tutor