Python: __dict__显示类对象的类属性,即使在__init__中的行为突变了类属性。

据我了解。

对于像list这样的可突变对象,如果底层对象像list一样支持突变,那么+=(增强赋值)就会导致对象的突变。当然,这对于不支持突变的不可变对象来说是行不通的,比如 __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中的新实例变量bar应该是影子类属性。但我看到,做 f.bar+=4 反过来也更新了类属性,这让我很困惑。

谁能帮我解决这个问题?

解决方案:

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

self.bar += [x]

相当于

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

所以, self.bar.__iadd__([x]) 变更列表,本质上是调用 list.extend然后,它 返回列表对象. 这个列表对象,是由 TestClass.bar,被分配给 实例属性.

所以现在你有了一个与类属性同名的实例属性,并且两者都恰好绑定到了同一个列表对象上。

这在 [文档] 中甚至被警告过。

对于属于属性引用的目标,同样的: 关于类和实例属性的注意事项 适用于常规任务。

但要注意的是:

给TA打赏
共{{data.count}}人
人已打赏
未分类

JSX React:使用ref选择文本框中的所有内容。

2022-9-7 23:39:21

未分类

在React material-ui选择菜单时,findDOMNode错误。

2022-9-7 23:50:16

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索