Python __init__从无处寻找变量

时间:2015-05-14 11:57:11

标签: python

我真的很难理解这种行为是如何出现的。我把它煮成尽可能小的例子,但仍会产生不良影响。

  • 我初始化一个类的实例,它的发起者特别指出,如果没有传递可选参数,它应该是一个空列表。
  • 然后我通过类上的方法添加一些数据,该方法应该充当实例方法。
  • 我创建了同一个类的新实例,同样没有将变量传递给启动器,但这次变量的填充就像魔法一样。

代码:

class Demo:
    def __init__(self, x=[]):
        self._x = x
        print x

    def add_x(self, data):
        self._x.append(data)

for x in range(0, 5):
    obj = Demo()
    obj.add_x([1, 2])

输出:

[]
[[1, 2]]
[[1, 2], [1, 2]]
[[1, 2], [1, 2], [1, 2]]
[[1, 2], [1, 2], [1, 2], [1, 2]]

我错过了什么?

2 个答案:

答案 0 :(得分:1)

在Python中,如果你使用[:],那么它不会创建一个新对象,而是指向相同的内存位置,而且我们知道列表是可变的,因此所做的任何更改都会反映在对该内存位置的所有引用中。现在,如果您有线性列表,则可以使用deepcopy();如果有嵌套列表,您也可以使用class Test: def __init__(self, x=list()): self._x = x[:] #Here is the magic print x def add_x(self, data): self._x.append(data)

yourString.matches(regex)

答案 1 :(得分:1)

def __init__(self, x=[]):
    self._x = x

在这种情况下,每当初始化没有参数的类实例时,self._x将引用同一个对象,而不是为每个实例创建一个新的空列表。实际上,self._x.append会附加到同一列表中。

建议的方法是

def __init__(self, x=None):
    if x is None:
        # create a new list
        x = []
    self._x = x

这适用于所有可变对象(例如dictset ...)。