Python使局部类在使用list.append(x)时变为全局变量,但在list=x时变为全局变量

Python使局部类在使用list.append(x)时变为全局变量,但在list=x时变为全局变量,python,Python,如果追加,则对象列表是全局的,但如果列表=值,则对象列表不是全局的 我创建了一个类,它接受一个列表,并将其用于数学函数。无论如何,我注意到这个系统有一个奇怪的怪癖:如果我附加元素x的列表,类中的所有对象都可以访问它,但是如果我设置list=x,那么列表就是本地的。X也是一个列表 class Wrong: list=[] def __init__(self, foo): for i in foo: self.list.append(i)

如果追加,则对象列表是全局的,但如果列表=值,则对象列表不是全局的

我创建了一个类,它接受一个列表,并将其用于数学函数。无论如何,我注意到这个系统有一个奇怪的怪癖:如果我附加元素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,以防发生任何变化。

您只需在
\uuuu init\uuu
函数中定义列表:

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)

您只需在
\uuuuu init\uuuu
函数中定义列表:

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)

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

  • 请求属性
  • 检查
    的实例属性是否存在。如果是,请退回
  • 如果未找到实例属性,请检查
    的类属性是否存在。如果是,请退回
  • 返回AttributeError,因为此实例没有命名属性

  • 这并不是因为它做得不对,而是因为您没有完全遵循它为您做的事情。

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

  • 请求属性
  • 检查
    的实例属性是否存在。如果是,请退回
  • 如果未找到实例属性,请检查
    的类属性是否存在。如果是,请退回
  • 返回AttributeError,因为此实例没有命名属性

  • 这并不是因为它做得不对,而是因为你没有完全遵循它为你做的事情。

    首先,不要给你的
    列表
    a
    列表
    命名,还要了解类和实例属性之间的区别。这也与。对于初学者,不要将您的
    列表命名为
    列表,您应该阅读,并了解类和实例属性之间的差异。这也与。不要像OP那样命名变量
    list
    ,如果你要发布答案,至少要确保你坚持正确的做法谢谢你的提示,我在这里很忙,所以我只是更正了代码。我将编辑:)即使知道他的例子只是一般性的,我认为你是对的@aws_学徒。不要像OP那样给变量命名
    list
    ,如果你要发布一个答案,至少要确保你坚持正确的做法谢谢你的提示,我在这里很忙,所以我刚刚更正了代码。我会编辑:)即使知道他的例子只是泛泛的,我想你是对的@aws_学徒。谢谢你。我总是假设你在init外部声明实例变量,然后在init内部给它们赋值。谢谢。我总是假设您在init外部声明实例变量,然后在init内部给它们赋值。