2009-12-08 101 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