Wyrażenie lambda w command= przy przypisywaniu funkcji do widgeta w Tkinter
To jest "przedruk" jednej z moich wypowiedzi na polskim forum Pythona. http://pl.python.org/forum/index.php?topic=4366.msg18668#msg18668
Poniższy opis odnosi się np. do kodu
Button(master, text="Wcisnij", command=...)
Do przekazywania argumentów w command
przydatna staje sie funkcja
lambda
... command=self.onButton # bez nawiasów
... command=lambda:self.onButton() # z nawiasami
... command=lambda:self.onButton(1,2,3)
Poniższe przypadki akurat w command
nie są przydatne (bo command
oczekuje funkcji, która nie wymaga przekazywania agumentów) ale gdyby
była potrzeba przypisania funkcji, do której będą przekazywane np. trzy
argumenty a my mamy funkcje, która wymaga więcej lub mniej argumentów
to:
... command=lambda x,y,z:self.onButton(1,2,3,x,y,z)
... command=lambda x,y,z:self.onButton()
Można też przypisać wartości domyślne argumentom i w przypadku
command
poniższe przypadki będą sobie równe
... command=lambda x=1,y=2,z=3:self.onButton(x,y,z)
... command=lambda:self.onButton(1,2,3)
Wartość można też wstawić tak
numer = 4
... command=lambda:self.onButton(numer)
ale do onButton
nie zostanie wstawiona na stałe wartość zmiennej
numer
tylko przy każdym wywołaniu tej funkcji lambda
będzie tam
wstawiana aktualna wartość zmiennej numer
Tak więc w takim przypadku
numer = 4
... command=lambda:self.onButton(numer)
numer = 99
może się okazać, że onButton
jako argument dostanie wartość 99.
W pewnych przypadkach może to być nawet przydatne ale na pierwszy rzut
oka nie takiej reakcji się spodziewany.
Widać to szczególnie w takim przypadku
for numer in range(1,4):
... command=lambda:self.onButton(numer)
Okazuje się, że powyższe nie będzie równoważne z
... command=lambda:self.onButton(1)
... command=lambda:self.onButton(2)
... command=lambda:self.onButton(3)
tylko z
... command=lambda:self.onButton(4)
... command=lambda:self.onButton(4)
... command=lambda:self.onButton(4)
bo po przejściu pętli zmienna numer
będzie miała wartość 4
Aby otrzymać oczekiwany wynik trzeba to zrobić tak
for numer in range(1,4):
... command=lambda x=numer:self.onButton(x)
podobnie jak tutaj
numer = 4
... command=lambda liczba=numer:self.onButton(liczba)
numer = 99
Buy a Coffee