2017-02-08 52 views
1

在lambda中執行多個語句是否可行?我的控制器中的app_data字典有一個屬性「listbox」,用於存儲選定的列表框值。 SelectPage上的按鈕有一個lambda命令,可將幀更改爲NextPage雙lambda Python

可以幀交換和app_data設置語句發生在雙拉姆達?如果是這樣,這可能是什麼樣子?或者這些操作必須單獨發生(即在按鈕點擊事件中)?

更新#1:

問題,因爲只是把一常數(即,1)在諸如.set(1)不保存任何分離到λ表達式。

更新#2: 使用帶有doStuff(controller)拉姆達有些解決了問題,但在列表框中參考引發錯誤:

value = self.listbox.get(self.listbox.curselection()) AttributeError: 'SelectPage' object has no attribute 'listbox'

按鈕:

button1 = ttk.Button(self, text='Next Page', 
         command=lambda:self.doStuff(controller)) 

doStuff():

def doStuff(self,controller): 
     controller.show_frame(NextPage) 
     controller.app_data["listbox"].set(1) 
     value = self.listbox.get(self.listbox.curselection()) 
     print(value) 
     print("do Stuff successful") 

全碼:

from tkinter import * 
from tkinter import ttk 



class MyApp(Tk): 
    # Controller class 
    def __init__(self): 
     Tk.__init__(self) 

     # App data in controller 
     self.app_data = {"listbox": StringVar(), 
         "entry":  StringVar(), 
         } 

     container = ttk.Frame(self) 
     container.pack(side="top", fill="both", expand = True) 
     self.frames = {} 
     for F in (SelectPage, NextPage): 
      frame = F(container, self) 
      self.frames[F] = frame 
      frame.grid(row=0, column=0, sticky = NSEW) 
     self.show_frame(SelectPage) 

    def show_frame(self, cont): 
     frame = self.frames[cont] 
     frame.tkraise() 

    def get_page(self,classname): 
     for page in self.frames.values(): 
      if str(page.__class__.__name__) == classname: 
       return page 
     return None 

class SelectPage(ttk.Frame): 

    def __init__(self, parent, controller): 
     self.controller = controller 
     ttk.Frame.__init__(self, parent) 
     ttk.Label(self, text='Select Page').grid(padx=(20,20), pady=(20,20)) 

     listbox = Listbox(self,exportselection=0) 
     listbox.grid() 
     for item in [0,1,2,3,4,5]: 
      listbox.insert(END, item) 
      print (item) 
     entry1 = ttk.Entry(self, textvariable=self.controller.app_data["entry"], width=8) 
     entry1.grid() 
     button1 = ttk.Button(self, text='Next Page', 
          command=lambda:self.doStuff(controller)) # something like this lambda concept 
     button1.grid() 

    def doStuff(self,controller): 
     controller.show_frame(NextPage) 
     controller.app_data["listbox"].set(1) 
     value = self.listbox.get(self.listbox.curselection()) 
     print(value) 
     print("do Stuff successful") 

class NextPage(ttk.Frame): 
    def __init__(self, parent, controller): 
     self.controller = controller 
     ttk.Frame.__init__(self, parent) 
     ttk.Label(self, text='Next Page').grid(padx=(20,20), pady=(20,20)) 
     button1 = ttk.Button(self, text='Select Page', 
          command=lambda: controller.show_frame(SelectPage)) 
     button1.grid() 
     button2 = ttk.Button(self, text='press to print', command=self.print_it) 
     button2.grid() 

    def print_it(self): 

     value = self.controller.app_data["listbox"].get() 
     print ('The value stored in StartPage some_entry = ' + str(value)) 
     value = self.controller.app_data["entry"].get() 
     print ('The value stored in StartPage some_entry = ' + str(value)) 
app = MyApp() 
app.title('Multi-Page Test App') 
app.mainloop() 
+4

可能的重複[是否可以在Python lambda表達式中包含多個語句?](http://stackoverflow.com/questions/862412/is-it-possible-to-have-multiple-statements-in-a-python-lambda-expression) –

+3

不要使用拉姆達,請使用適當的函數與'def'。注意:如果需要,可以在函數中定義函數並使用其本地名稱空間。 – Lagerbaer

+0

當你嘗試時發生了什麼?您的代碼是否按預期工作? – Goyo

回答

2

您的原始lambda沒有工作,因爲show_frame(...)回報無,這短路and因此剩下的表達不執行。只需將其更改爲or即可。由於事件的調用者並不關心你返回的內容,所以你也可以爲這兩個子表達式創建兩個項目tuple。還有其他問題,例如self.listbox不存在,我固定,但其他人仍然存在。

作爲一個迂腐的人,lambda只接受一個表達式,這是一個語句的子集。

self.listbox = listbox 
button1 = ttk.Button(self, text='Next Page', 
        command=lambda: controller.show_frame(NextPage) or self.controller 
        .app_data["listbox"] 
        .set(self.listbox.get(self.listbox.curselection()))) # something like this lam 
2

Is it feasible to execute multiple statements in a lambda?

號一般情況下,你應該避免使用lambda可言,當你必須使用它,你需要保持它儘可能簡短。如果您需要調用多個函數,請創建一個調用其他函數的新函數。

此外,如果您傳遞的參數只是對象的屬性,則根本不需要lambda。我認爲下面的代碼更容易閱讀,更容易理解,寫起來更容易,因而更容易維護:

button1 = ttk.Button(self, text='Next Page',command=self.doStuff) 
... 
def doStuff(self): 
    self.controller.show_frame(NextPage) 
    self.controller.app_data["listbox"].set(1)