求助,急,关于python的类属性__slots__,为什么修改类属性影响实例?

作者站长头像
站长
· 阅读数 7
class Person:
    __slots__ = ("name")
    def __init__(self):
        self.name=13
shili=Person()
print(shili.name)
# Person.name = 143
print(id(shili.name),id(Person.name))

Person.name = 143
print(id(shili.name),id(Person.name))
shili.name=13

我有以上代码,为什么修改类属性影响实例属性?有人会说这是由于实例共享类属性,根据mro属性解析顺序是如此,但是这是在实例命名空间没有要搜索的属性时才会访问类的命名空间,在我的代码中,实例(shili)有自己的name属性,但为什么还是共享类属性呢?或者说这是其他什么问题,求大佬解答

回复
1个回答
avatar
test
2024-07-02

这里有一个知识点,可以记笔记:在 Python 中,实例属性和类属性都是存储在对象的命名空间中的,默认情况下,实例属性会覆盖同名的类属性。

我们以你的这段代码为例,阐释每一段代码的含义从而有利于更好理解,我们首先定义了一个类 Person,其中包含一个类属性 name,并且使用 slots 限制了实例属性。创建 shili 实例后,我们访问实例的 name 属性,这时实例并没有自己的 name 属性,因为在初始化时它只能拥有 slots 中指定的属性。所以,Python 会到 shili 对象所属的类 Person 中查找属性 name,然后输出其值 13。

接着,我们将类属性 name 修改为 143,此时 shili 实例的 name 属性并未被修改,因为实例属性会覆盖同名的类属性。但是,我们打印出了 shili.name 的内存地址和 Person.name 的内存地址,发现它们的内存地址相同,这说明 shili 实例的 name 属性实际上是类属性的引用。因此,当我们再次访问 shili.name 时,它实际上是访问的类属性,因此输出结果为 143。这是因为 Python 中,类属性在各个实例之间是共享的,因为它们都指向同一个内存地址。

真诚的希望我的回答能帮到您!

回复
likes
适合作为回答的
  • 经过验证的有效解决办法
  • 自己的经验指引,对解决问题有帮助
  • 遵循 Markdown 语法排版,代码语义正确
不该作为回答的
  • 询问内容细节或回复楼层
  • 与题目无关的内容
  • “赞”“顶”“同问”“看手册”“解决了没”等毫无意义的内容