Python类共享变量提供了意外的输出

时间:2016-08-30 18:06:26

标签: python class oop

基于Shared Variables in Python Class的解释,我希望以下代码将输出提供为:

123 123
200 200
300 300

但它是

123 123
200 123
200 300

代码:

class A:
    abc = 123
    def __init__(self, a,b,c):
        self._a = a
        self._b = b
        self._c = c


if __name__ == '__main__':
    a = A(2, 4, 6)
    b = A(3, 9, 27)

    print a.abc , b.abc
    a.abc = 200
    print a.abc , b.abc
    A.abc = 300
    print a.abc , b.abc

有人可以帮忙理解这个吗?我的印象是共享变量与C ++类中的静态变量相同。任何洞察这个神话的见解,如果是这样,也会有所帮助。

4 个答案:

答案 0 :(得分:4)

您正在创建一个新的实例变量 - > a.abc并将其设置为200。改为访问共享静态变量。

a = A(2, 4, 6)
b = A(3, 9, 27)
print a.abc , b.abc
A.abc = 200  # Set static class variable, instead of creating new instance member
print a.abc , b.abc
A.abc = 300
print a.abc , b.abc

我建议您阅读[9] Classes上提供信息丰富的Python官方文档。

答案 1 :(得分:4)

最初,A类的abc定义为123,ab各使用,因为它们都没有abc

然后执行a.abc = 200,为abc创建a; b仍然使用A中的那个。

然后执行A.abc = 300,更新abc的{​​{1}},A仍然会查看,以便查看新值。但是b有自己的a,所以并不关心。

答案 2 :(得分:0)

@Scott Hunter's answer最好地解释了有问题的代码的行为,但我想在这里添加C ++透视图。不幸的是,它不能作为评论添加到答案中,因为它太长了。

与在C ++中一样,要访问静态成员名称需要通过类名限定(例如A::abcA::func_static()),在Python中您还必须使用类名访问类外的共享变量作为资格赛。

在类中,C ++允许像其他成员变量一样使用静态变量名(即没有任何限定符),Python也是如此,因为共享变量可以使用自己访问,例如self.abc这里。

只有与此不同的是Python允许您创建一个与该实例的共享变量同名的实例变量。

答案 3 :(得分:-1)

您的预期输出意味着您无法在不更改对象类的每个实例的属性的情况下更改对象的属性。这显然会打破面向对象理念的核心。我认为你可以覆盖“共享”变量,因为这提供了更多的可能性。