静态类变量和Python中的`self`

Kon*_*tin 2 python oop static class self

为什么下面的例子表现不一样?

示例1:foo似乎表现为特定于各种对象的类变量

class A: 
    foo = 1
a, b = A(), A()
a.foo = 5
print b.foo
----------------
Output: 1
Run Code Online (Sandbox Code Playgroud)

示例2:foo似乎表现得像所有对象的静态类变量一样.也许这种行为与作为指针的列表有关.

class A: 
    foo = []
a, b = A(), A()
a.foo.append(5)
print b.foo
----------------
Output: [5]
Run Code Online (Sandbox Code Playgroud)

示例3:不起作用

class A: 
    self.foo = []
a, b = A(), A()
a.foo.append(5)
print b.foo
----------------
Output: Error
Run Code Online (Sandbox Code Playgroud)

Bre*_*arn 6

前两个示例都是类属性.它们看起来不同的原因是因为在两种情况下你都没有做同样的事情:你在第一种情况下分配一个新值,在第二种情况下修改现有值.

请注意,前两个示例中您没有做同样的事情.在第一个示例中a.foo = 5,指定一个新值.在第二个例子中,如果你做了类似的事情,分配a.foo = [5],你会看到与第一个例子中相同的结果.但相反,您改变了现有列表a.foo.append(5),因此行为不同. a.foo = 5仅更改变量(即,它指向的值); a.foo.append(5)改变价值本身.

(请注意,没有办法在第一个示例中执行第二个示例的等效.也就是说,没有什么a.foo.add(1)比添加1到5.这是因为整数不可变但列表是.但重要的不是那个列表"是"可变的,但是你突然改变了一个.换句话说,你可以用列表做什么并不重要,重要的是你在特定的代码中实际做了什么."

另请注意,虽然foo您在类定义中定义的是类属性,但是在执行时a.foo = 5,您将在实例上创建新属性.它碰巧与class属性具有相同的名称,但它不会更改class属性的值,这b.foo仍然是可见的.

最后一个示例不起作用,因为,就像在前两个示例中一样,class块内的代码位于类范围内.没有,self因为在定义类时还没有实例.

StackOverflow上有很多很多关于此的问题,我恳请您搜索并阅读其中的一些问题,以便更全面地了解其工作原理.