Python 类变量与所有实例共享

时间:2021-04-09 03:49:26

标签: python python-3.x python-class

class list_class:
        def __init__(self, list_=[]):
                self.list_ = list_

        def add_item(self, item):
                self.list_ += [item]
>>> x = list_class()
>>> y = list_class()
>>> x.list_
[]
>>> y.list_
[]
>>> x.add_item(1)
>>> x.list_
[1]
>>> y.list_
[1]

为什么在 x 上调用 add_item() 会改变两个实例上的 list_ 变量?

2 个答案:

答案 0 :(得分:0)

在方法参数中使用 list_=[] 是一个糟糕的 Python 习惯用法,原因您已经发现。请改用以下内容:

class ListClass:
    def __init__(self, list_=None):
        if list_ is None:
            list_ = []
        self.list_ = list_

    def add_item(self, item):
        self.list_.append(item)
当最初解析 list_ 时,

[] 设置为 __init__。但是,列表是可变的,并且不会在赋值时复制。因此,当 __init__ 方法运行时,每次都使用相同的初始列表。通过上述替换,每次运行 list_ 时,__init__ 都会被分配给一个 new 列表,从而避免了问题。 dict 作为函数参数值的默认值也是如此。列表或字典是否为空或包含值都没有关系(__init__(self, list_=[5]) 会遇到同样的问题:不要在函数参数中使用可变变量作为默认值。

the warning in the tutorial section of default function arguments

其他更多 Pythonic 习语使用 CamelCase 作为类名,并使用 somelist.append(item) 而不是 somelist += [item]

答案 1 :(得分:0)

我见过几次,但不记得最终原因。解决方案是不要(或永远不要)在您的函数/类中声明空的可迭代对象。

class List_Class:
    def __init__(self, list_):
        self.list_ = list_

    def add_item(self, item):
        self.list_ += [item]


x = List_Class(list())
y = List_Class(list())
print(x.list_)
print(y.list_)
x.add_item(1)
print(x.list_)
print(y.list_)
相关问题