2009-12-08 183 views
3

我在Python中遇到了一個(對我來說)非常奇怪的問題。Python參考問題

我有一個類稱爲菜單:(片段)

class Menu: 
    """Shows a menu with the defined items""" 
    menu_items = {} 
    characters = map(chr, range(97, 123)) 

    def __init__(self, menu_items): 
     self.init_menu(menu_items) 

    def init_menu(self, menu_items): 
     i = 0 
     for item in menu_items: 
      self.menu_items[self.characters[i]] = item 
      i += 1 

當我實例化類,我通過在字典列表。詞典都使用此函數創建:

def menu_item(description, action=None): 
    if action == None: 
     action = lambda : None 
    return {"description": description, "action": action} 

然後創建列表如下:

t = [menu_item("abcd")] 
m3 = menu.Menu(t) 

a = [ menu_item("Test")] 
m2 = menu.Menu(a) 

b = [ menu_item("Update", m2.getAction), 
         menu_item("Add"), 
         menu_item("Delete")] 
m = menu.Menu(b) 

當我運行我的程序,我每次得到相同的菜單項。我已經使用PDB運行程序,並且一旦創建了另一個類的實例,就會立即發現所有以前類的menu_items被設置爲最新列表。看起來好像menu_items成員是靜態成員。

我在這裏監督什麼?

回答

16

menu_items的字典是這是所有Menu實例之間共享的類屬性。初始化像這樣,而是和你應該罰款:

class Menu: 
    """Shows a menu with the defined items""" 
    characters = map(chr, range(97, 123)) 

    def __init__(self, menu_items): 
     self.menu_items = {} 
     self.init_menu(menu_items) 

    [...] 

看一看在Python tutorial section on classes有關類屬性和實例屬性之間的差異更深入的討論。

+0

非常有用的功能是什麼原因,他們都共享這種方式? – Ikke 2009-12-08 13:52:16

+4

不,這是因爲您將'menu_items'定義爲類屬性(直接在'Menu Menu'內)而不是實例屬性(在類的方法中初始化)。 – 2009-12-08 13:54:08

+0

它以這種方式工作的原因(很像其他語言中的靜態屬性)是您有時希望能夠在實例之間共享數據。我加入我的答案鏈接到Python的教程,你可以閱讀更多關於類和實例的屬性如何工作。 – 2009-12-08 14:01:26

5

由於PAR這裏回答你的問題是一些隨機的建議:dictzip是:-)

class Menu: 
    """Shows a menu with the defined items""" 
    characters = map(chr, range(97, 123)) 

    def __init__(self, menu_items): 
     self.menu_items = dict(zip(self.characters, menu_items)) 
+0

謝謝,我忘記了zip功能。 – Ikke 2009-12-08 14:12:02