Skip to main content
 首页 » 编程设计

类和实例变量的 Python 引用

2025年05月04日27jackei

我已经阅读了许多关于 Python 中的变量引用的问题,但是当我使用我不期望的代码并且它变得非常令人沮丧时,事情仍然在发生。拿这段代码:

class MyClass(object) : 
 
    class_var = "original message" # same for all objects 
 
    def __init__(self, instance_var) : 
        self.instance_var = instance_var #particular to the object 
 
my_object = MyClass("my instance variable") 
untouched_object = MyClass("another instance_var") 
 
# Values of class_var and instance_var as expected 
 
MyClass.class_var = "changed message" 
 
# attribute class_var has changed for both objects 
 
# This changes attribute class_var for my_object only 
my_object.class_var = "I am my_object" 
 
# THIS ONLY CHANGES ATTRIBUTE CLASS_VAR FOR UNTOUCHED_OBJECT ONLY! 
MyClass.class_var = "Last message" 
 
print MyClass.class_var #prints Last Message 
print my_object.class_var #prints I am my_object ??? 
print untouched_object.class_var #prints Last Message 

这是怎么回事?当我使用类变量创建某个类的对象时,似乎 object.class_attribute 最初包含指向 Class.class_var 的指针,我可以更改所有对象的属性通过分配给 Class.class_var。但是,如果我明确地将 object.class 属性分配给其他一些值,指针就会消失并且更改 Class.class_var 不再对该特定对象的更改产生影响,只有所有其他实例。这是怎么回事?此外,为什么我们能够以这种方式访问​​和更改类属性并可能无法访问 Python 文档声称所有实例都知道的值?

请您参考如下方法:

当你这样做的时候

my_object.class_var = "I am my_object" 

您创建了一个实例 属性my_object.class_var,它隐藏了类属性MyClass.class_var,因此看来随后对MyClass.class_var 对 my_object 没有影响。

尝试根据其他语言的概念(例如引用和指针)来理解 Python 的数据模型可能会产生误导。尝试根据名称以及对象与名称的绑定(bind)来思考。

因此在您的示例中,MyClass.class_var 和 my_object.class_var 最初都是绑定(bind)到类属性的名称,但赋值将新的字符串对象绑定(bind)到名称我的对象.class_var。

我发现将 (name, object) 对视为字典中的 (key, value) 对会有所帮助。在某些情况下,这实际上是“幕后”发生的事情(例如,使用您自己创建的普通类),但在其他情况下(例如 Python 的内置类型),出于效率的原因,事情的实现略有不同。

您可能会发现这篇文章很有帮助:Facts and myths about Python names and values ,由 SO 资深人士 Ned Batchelder 撰写。