如果使用list.append(x),Python会使局部类成为全局变量,但如果list = x,则不会

时间:2019-02-04 17:02:39

标签: python

对象列表是全局的(如果追加),但不是,如果list = value

我创建了一个类,它包含一个列表,并将其用于数学函数。无论如何,我注意到系统存在一个奇怪的怪癖:如果我追加元素x的列表,则该类中的所有对象都可以访问它,但是如果我设置list = x,则该列表是本地的。 X也是一个列表。

class Wrong:
    list=[]

    def __init__(self, foo):
        for i in foo:
            self.list.append(i)

class Right:
    list=[]

    def __init__(self, foo):
        self.list=foo

list=[1,2,3]
wrong1 = Wrong(list)
wrong2 = Wrong(list)
right1 = Right(list)
right2 = Right(list)

print(wrong1.list)
print(wrong2.list)
print(right1.list)
print(right2.list)

我希望输出是相同的,但是在打印时,是

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

我正在使用python 3.7.2,以防万一。

2 个答案:

答案 0 :(得分:2)

您误解了什么是类属性和实例属性。在第一个示例中,您已将Wrong.list声明为类属性,该属性将在Wrong的所有实例之间共享。在第二个示例中,您创建了Right的实例,然后将其对类属性Right.list的引用替换为对名为self.list的实例属性的新引用。访问属性时,查找层次结构如下所示:

  1. 请求属性<name>
  2. 检查<name>的实例属性是否存在。如果是,则将其退回。
  3. 如果未找到实例属性,请检查<name>的类属性是否存在。如果是,则将其退回。
  4. 返回AttributeError,因为此实例没有命名的属性。

这并不是说它做错了什么,而是您没有完全了解它为您所做的事情。

答案 1 :(得分:0)

您只需要在__init__函数中定义列表:

class Wrong:

    def __init__(self, foo):
        self.y = []
        for i in foo:
            self.y.append(i)

class Right:

    def __init__(self, foo):
        self.z = foo

x = [1,2,3]
wrong1 = Wrong(x)
wrong2 = Wrong(x)
right1 = Right(x)
right2 = Right(x)

print(wrong1.y)
print(wrong2.y)
print(right1.z)
print(right2.z)