为什么我的类变量没有针对所有实例进行更改?

问题描述 投票:0回答:3

我正在学习课程,但不明白这一点:

class MyClass:
    var = 1

one = MyClass()
two = MyClass()

print(one.var, two.var) # out: 1 1
one.var = 2

print(one.var, two.var) # out: 2 1

我认为类变量可以被所有实例访问,但为什么它不会对所有实例进行更改?

python class oop instance class-variables
3个回答
4
投票

对于所有这些都不会改变,因为这样做:

one.var = 2
,创建了一个新的实例变量 与类变量同名,但仅适用于实例
one
。 之后,
one
将首先找到它的实例变量并返回它,而
two
只会找到类变量并返回它。

要更改类变量,我建议有两种选择:

  1. 创建一个类方法来更改类变量(我的偏好)

  2. 直接使用类来改变它

class MyClass:
    var = 1

    @classmethod
    def change_var(cls, var): 
        cls.var = var


one = MyClass()
two = MyClass()

print(one.var, two.var) # out: 1 1

one.change_var(2)  # option 1
print(one.var, two.var) # out: 2 2

MyClass.var = 3     # option 2
print(one.var, two.var) # out: 3 3

2
投票

通过实例对属性赋值总是创建/更新实例变量,无论是否存在同名的类属性。要更新类属性,您必须使用对该类的引用。

>>> type(one).var = 2
>>> print(one.var, two.var)
2 2

在实践中,

type(one)
可能会返回错误类来更新特定的类属性,但实际上,当您只有一个可用的类实例时,您不需要更改类属性。


0
投票

one.var = 2
实际上是按对象添加新实例变量
var
,但不更改类变量
var
,添加新实例变量
var
后,
one.var
访问新的实例变量
var
如下所示。 *如果存在同名类和实例变量,则同名实例变量优先,而同名类变量被对象访问时被忽略:

class MyClass:
    var = 1

one = MyClass()
two = MyClass()

print(one.var, two.var) 
one.var = 2 # Adds the new instance variable by object
                # ↓ Accesses the class variable by object 
print(one.var, two.var)
   #     ↑
   # Accesses the new instance variable by object

输出:

1 1
2 1

因此,要更改类变量

var
,您需要使用类名
MyClass
,如下所示:

class MyClass:
    var = 1

one = MyClass()
two = MyClass()

print(one.var, two.var) 
MyClass.var = 2 # Changes the class variable by the class name

print(one.var, two.var)

输出:

1 1
2 2

基本上,您应该使用类名来访问类变量,因为无论是否存在同名实例变量,您始终可以访问类变量。因此,使用类名比使用对象访问类变量更安全,如下所示:

class MyClass:
    var = 1

one = MyClass()
two = MyClass()
      # Here       # Here
print(MyClass.var, MyClass.var)
MyClass.var = 2 # Changes the class variable by the class name
      # Here       # Here
print(MyClass.var, MyClass.var)

输出:

1 1
2 2

我的答案如何在Python中访问“静态”类变量?解释了有关访问类变量的更多信息

© www.soinside.com 2019 - 2024. All rights reserved.