类和实例变量的 Python 引用

标签 python python-2.7 variables reference namespaces

我已经阅读了许多关于 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_varmy_object 没有影响。

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

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

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

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

关于类和实例变量的 Python 引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35952278/

相关文章:

python - 用asyncore实现gethostbyaddr()

python - 调用元类基础时出错

powershell - 计算变量

javascript - 使用 javascript 变量更改 css 背景颜色

c# - MVVMCross 将值传递给具有 2 个构造函数的 ViewModel

python - 如果列包含 Pandas 中的任何字符串值,则从数据框中删除值

python - 为什么开集永远不会变为 0?

Python输出长度

python - 从 tdms 文件中分割一维 numpy 数组,并从原始数组中绘制较短的时间序列/间隔

Python 和 Dropbox : How to change SmartSync setting for locally created files?