在类中添加列表(Python)

3

我在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个回答

15

因为buttonlist是一个类变量,而不是实例变量。如果你想让它局限于实例,则需要在构造函数中进行赋值。

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

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


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。但这并不是必须的。

1
我建议您在AV.__init__中使用super(AV, self).__init__()代替Menu.__init__(self),并在Main.__init__中进行相应的更改(因为没有括号的print,所以我推断这是Python 2.x)。 - tzot

1
是一个类属性,也是可变的(列表)

由于没有在基类的<__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 

 

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

lst = []
lst.append(av(14))
lst.append(av(12))
print(str(lst[0]) + str(lst[1]))

4
即使这是解决方案,也请为您的代码写一些解释。 - Lamanus
1
请不要只发布代码作为答案,而是包括一个解释你的代码是如何解决问题以及其原理的说明。带有解释的答案通常更具质量,并更有可能吸引赞同。 - Mark Rotteveel

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接