Python:即使__init__内部的行为使class属性发生突变,__ dict__也会显示该类对象的类属性

Sushrut Kaul:

据我了解,

对于诸如列表之类的可变对象,如果基础对象支持诸如列表之类的变异,则+ =(增加的赋值)会导致该对象的变异。当然,这对于不支持__iadd__不存在的突变的不可变对象不起作用,它__add__是被调用的对象。

考虑以下代码:

class TestClass:
    bar = []

    def __init__(self, x):
        self.bar += [x]


f = TestClass(1)
g = TestClass(2)
h = TestClass(3)
print(f.bar)
print(g.bar)
print(TestClass.bar)

现在,我理解了为什么三个g,f,h都打印出来了,[1, 2, 3]因为我们正在“改变”类属性。

但是,当我尝试通过这样做print(f.__dict__)查看对象的名称空间时,我也看到了对象内部的bar属性。

问题1:如果被突变的实际属性是类属性,为什么在对象名称空间中创建实例?

其次,“如果”实例变量是在对象中创建的(如f),则f.bar += 4应该只影响对象f,因为f中的新实例变量栏可能会遮盖类属性。但是我看到这样做f.bar+=4反过来也会更新class属性,这对我来说完全令人困惑。

有人可以帮我吗?

juanpa.arrivillaga:

这可能有点微妙。你可以想到

self.bar += [x]

相当于

self.bar = self.bar.__iadd__([x])

因此,self.bar.__iadd__([x])对列表进行突变(本质上是调用)list.extend,然后返回列表对象此列表对象与引用的对象相同TestClass.bar,已分配给instance属性

因此,现在您有了一个实例属性,它的名称与类属性的名称相同,并且都碰巧绑定到了相同的列表对象

甚至在[documentation]中也警告过:

对于作为属性引用的目标,关于类和实例属性的警告同样适用于常规分配。

需要注意的是:

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

被属性遮盖时修改类__dict__

__dict__ Ultimate Base Class的属性,Python中的对象

Python类的__dict __.__ dict__属性是什么?

如何通过__dict__分配新的类属性?

一个类可以具有一个Map属性,该类属性将Class对象作为键,并将其值作为该类对象的列表?

用__dict__列出实例属性

在__init__中更改类属性

对象在python3中没有属性'.__ dict__'

如何通过Google的自然语言API JSON序列化对象?(没有__dict__属性)

如果对象不具有__dict__,则其类是否必须具有__slots__属性?

为什么自定义Python类实例的`__dict__`属性是该类的描述符,而不是实例的实际属性?

“ C .__ dict__”输出中的“ <C对象的<xxx属性> xxx”是什么意思?

__dict__不了解类的某些属性

混合对象注入后Python对象丢失__dict__

如果未在__init__中定义该属性,则显示该类的属性。

在class1中调用class2时发生AttributeError,class1没有__init__属性

如果通过该类的实例设置类属性会发生什么?

__dict__用于不显示@property属性的对象

比较对象类型的类属性

通过实例方法突变类属性引用的对象

类属性未按预期显示

并行和有条件的:NoneType对象没有属性“ __dict__”

类属性的顺序会影响对象的大小吗?

python cffi库对象自省导致__dict__对象更改

python类的属性不在__init__中

“对象没有 __dict__,因此您不能将任意属性分配给对象类的实例。”

调用 help(MyClass) 也会显示基类属性:如何避免这种情况?

为什么我的类工厂没有填充我的动态对象的 `__dict__` 属性

在类 __init__ 之外定义的 Python 属性对象