python3共享可变属性吗?

时间:2018-12-07 08:50:41

标签: python python-3.x mutable

在代码中,我实例化了同一类的两个不同对象,object1怎么可能改变object2的属性?如何保留不同的“ self.mutable”变量?我的错在哪里:-)

谢谢

class Class:
    mutable = {}
    immutable = 0

    def change(self):
        self.immutable = 1
        self.mutable["key"] = "value"

    def observe(self):
        print(self.immutable, self.mutable)


object1, object2 = Class(), Class()

object1.change()
object2.observe()
# output is: 0 {'key': 'value'}

1 个答案:

答案 0 :(得分:4)

您已经在课程级别定义了mutableimmutable, 因此,在Class的所有实例中,两者都是shared。链接问题中的答案详细说明了如何避免您观察到的共享行为,因此,我将仅解释代码的内容。

原则上,这种共享与可变或不可变的属性无关,但是您的代码中有一些细微差别可能会使它们造成混淆。

对于mutable,观察到的行为很容易解释。

首先,字典mutable始终是内存中的同一对象:

>>> o1, o2 = Class(), Class()                                                                         
>>> o1.mutable is o2.mutable is Class.mutable                                                         
True

当您mutate以任何方式进行更改时,只要持有该格言,该更改就会随处可见。

>>> Class.mutable                                                                                     
{}
>>> o2.mutable[1] = 2                                                                                 
>>> o1.change()                                                                                       
>>> Class.mutable                                                                                     
{1: 2, 'key': 'value'}

到目前为止,所有这一切都是可以预期的。 immutable的棘手部分是您不会更改Class.mutable的变化,而是将mutable属性self分配给实例(changeimmutable正在被调用!

在调用change之前,o1仅存在于类级别,并且在实例o2o1上进行查询时可通过该类进行访问。 (请注意,o2>>> o1, o2 = Class(), Class() >>> o1.immutable, o2.immutable, Class.immutable (0, 0, 0) >>> o1.__dict__, o2.__dict__, 'immutable' in Class.__dict__ ({}, {}, True) 的实例字典是空的。)

change

o2上调用immutable = 1时,只需在实例o2上设置属性>>> o2.change() >>> o1.immutable, o2.immutable, Class.immutable (0, 1, 0) >>> o1.__dict__, o2.__dict__, 'immutable' in Class.__dict__ ({}, {'immutable': 1}, True) >>> o1.immutable is Class.immutable True >>> o2.immutable is Class.immutable False

self.mutable = {'key': 'value'}

重要的是要理解,以完全相同的方式共享在类级别设置的可变对象和不可变对象。唯一的区别是,可变对象上没有更改它们的方法。但是,如果您在change中完成过change,然后在特定实例上调用了mutable,则在实例上定义的<system.web> <customErrors mode="Off"> </customErrors> <authentication mode="None" /> <compilation targetFramework="4.5.2" /> <httpRuntime targetFramework="4.5" /> <caching> <outputCacheSettings> <outputCacheProfiles> <add name="CacheOneDay" duration="86400" varyByParam="IFAID" /> </outputCacheProfiles> </outputCacheSettings> </caching> <sessionState timeout = "60" mode = "InProc" /> </system.web> 属性将优先于在类中定义的属性通过点符号在实例上查找时的级别。