在类中追加列表(python)

3 投票
4 回答
54486 浏览
提问于 2025-04-16 18:31

我在使用Python的继承时遇到了一个问题,我知道怎么避免这个问题,但并不完全理解。这个问题发生在我制作菜单的时候,不过我把代码简化了,只保留了真正的问题。

class menu:
    buttonlist=[]

>>> class av(menu):
    def __init__(self, num):
        self.buttonlist.append(num)
        print self.buttonlist

>>> AV=av(12)
[12]
>>> class main(menu):
    def __init__(self, num):
        self.buttonlist.append(num)
        print self.buttonlist

>>> Main=main(14)
[12, 14]
>>> AV.buttonlist
[12, 14]

我本来期待通过'Main=main(14)'能得到[14],通过'AV.buttonlist'能得到[12],但结果似乎是append把列表添加到了所有的类和对象里 :S

有人能告诉我这是为什么吗?

提前谢谢大家!

4 个回答

1

buttonlist是一个类属性,而且它是可变的(因为是列表)。

因为buttonlist没有在基类的__init__方法中定义,所以它是一个类变量,而不是实例变量。这意味着所有继承这个类的地方对它的修改都会影响到它。换句话说,它不属于任何一个继承它的类,而是属于所有的实例。第一个实例添加了12,第二个实例添加了14。

#Main and AV.buttonlist are actually different, 
print Main
print AV
#you should get something similar to this pointing to different locations
<__main__.main object at 0x02B753F>
<__main__.av object at 0x02B6B910>

#obviouly different objects but inheriting from the same class. Thus,the class variable changes, keeps appending
class menu:
    buttonlist=""

class av(menu):
    def __init__(self, num):
        self.buttonlist = num


class main(menu):
    def __init__(self, num):
        self.buttonlist = num

a=av("food")
b=main("menu")

print(menu.buttonlist)
print(a.buttonlist)
print(b.buttonlist)

##won't work for strings as they are immutable and can't be changed after delared in the base class 

 
5

@Cat 先我一步,不过这里有一些可用的代码

class Menu(object):
    def __init__(self):
        self.buttonlist = []

class AV(Menu):
    def __init__(self, num):
        Menu.__init__(self)
        self.buttonlist.append(num)
        print self.buttonlist

class Main(Menu):
    def __init__(self, num):
        Menu.__init__(self)
        self.buttonlist.append(num)
        print self.buttonlist

>>> av = AV(12)
>>> main = Main(14)

需要注意的是,Python 中的类名通常使用大驼峰命名法,也就是说你的 av 类应该叫 AV,而 menu 则应该叫 Menu。不过这并不是强制要求的。

15

因为 buttonlist 是一个类变量,而不是实例变量。如果你想让它只属于某个特定的实例,你需要在构造函数里给它赋值。

class menu:
    def __init__(self):
        self.buttonlist = []

然后,当然要记得在派生类中调用基类的构造函数。

撰写回答