Python __slots__下,修改类属性会影响实例属性吗?

Python __slots__下,修改类属性会影响实例属性吗?

python __slots__ 与实例属性的关联性

本文深入探讨 Python 中 __slots__ 的用法,以及修改类属性为何会影响实例属性,特别是当实例已拥有该属性时。

让我们先看一段代码:

class Person:     __slots__ = ("name",)  # 注意这里加了逗号,变成tuple     def __init__(self):         self.name = 13  shili = Person() print(shili.name)  # 输出 13 print(id(shili.name), id(Person.name)) # 输出 shili.name 和 Person.name 的内存地址  Person.name = 143 print(id(shili.name), id(Person.name)) # 输出 shili.name 和 Person.name 的内存地址,两者相同  shili.name = 13 print(shili.name) # 输出 13

这段代码定义了 Person 类,并使用 __slots__ 限制实例属性为 “name”。 初始化实例 shili 时,我们为其设置了 name 属性。 值得注意的是,即使 shili 已经拥有自己的 name 属性,修改类属性 Person.name 后,shili.name 的值也会随之变化。 这并非实例属性继承或优先级问题,而是由于 __slots__ 的工作机制。

立即学习Python免费学习笔记(深入)”;

__slots__ 限制了实例可拥有的属性,但它并没有阻止实例属性指向类属性。 当创建 shili 实例并赋值 self.name = 13 时,Python 并没有为 shili 创建新的 name 属性,而是让 shili.name 指向了类属性 Person.name。 因此,修改 Person.name 时,shili.name 也指向了新的内存地址,从而改变了它的值。 第一次打印 id(shili.name), id(Person.name) 时,两个 ID 相同,证实了这一点。 只有当 shili.name 被重新赋值后,才为 shili 创建了新的 name 属性,此时 shili.name 和 Person.name 指向不同的内存地址。

总结:使用 __slots__ 时,需特别注意实例属性与类属性的关系。 虽然 __slots__ 限制了实例属性的创建,但如果实例属性未被显式创建,它会指向类属性,导致修改类属性会影响实例属性。 只有当实例属性被显式赋值后,实例才拥有独立的属性,此时修改类属性不会再影响实例属性。

© 版权声明
THE END
喜欢就支持一下吧
点赞9 分享