python - Deciphering a lambda expression -


i have been following closely, youtube video in order create on-screen keyboard using tkinter.

i understand of going on; create our buttons within list , loop through buttons, inserting rows @ best position create looking keyboard.

the problem i've been having task, when click button, text of button gets inserted entry box via tkinter.

the way in this, assign command button, , upon pressing it, calls anonymous function, assigning button pressed 'x' parameter. pass parameter method , insert value entry widget.

i'm trying understand, why can't pass in button itself, instead have assign button parameter...

self.textbox = textbox  row=0 col=0  buttons = [     '1','2','3','4','5','6','7','8','9','0',     'q','w','e','r','t','y','u','i','o','p',     'a','s','d','f','g','h','j','k','l',     'z','x','c','v','b','n','m','end']  button in buttons:     # why not following command instead?     # command = lambda: self.command(button)     command = lambda x=button: self.callback(x)     if button != 'end':         tk.button(self, text=button, width=5,             command=command).grid(row=row, column=col)     col+=1     if col > 9:         col=0         row+=1  def command(self, button):     x = button     self.callback(x)  def callback(self, value):     self.textbox.insert(tk.end, value) 

with above code, can insert desired value entry widget. however, if use code have commented out, instead insert 'end' entry widget.

i have tried replicate lambda function separate method, still inserting 'end' entry widget.

# using commented code above , passing in button parameter def command(self, button):     x = button     self.callback(x)  def callback(self, value):     self.textbox.insert(tk.end, value) 

i thought if able replicate function non-anon function, work, not.

what lambda function doing , there way replicate using non-anonymous function (ie. method)?

the problem with

for button in buttons:     command = lambda: self.command(button) 

is command equal lambda: self.command(button), passed button constructor. command of button instance equal lambda: self.command(button). think self.command(button) evaluated, , replaced result of following:

def command(self, button):     x = button     self.callback(x) 

however, there no reason so: since self.command(button) inside of lambda function, evaluated when the lambda will called.

as consequence, when executing created lambda function, button evaluated last value assigned, not value had when the lambda was created. therefore, after loop, of lamda functions have same behaviour, , button inside of body point toward same button instance.


if want have method instead of lambda, can wrap command method inside of command builder:

def build_command(self, button):     def command():         self.callback(button)      return command 

then call method expected command:

command = self.build_command(button) 

the reason why works, button variable local build_command, , inner command "inherits" variable own local variable dictionary (given locals()). local dictionary stay unaffected outer changes.


Comments

Popular posts from this blog

neo4j - finding mutual friends in a cypher statement starting with three or more persons -

php - How to remove letter in front of the word laravel -

minify - Minimizing css files -