首页 > 解决方案 > 实例和类变量的实现

问题描述

我很好奇Python的类和实例变量的实现。我在文档中找不到答案,坦率地说,我并不想深入了解所有 Python 源代码。

这些属性可以总结如下:

这在下面演示

>>> class cA:
...     pub = "public"
...     def __init__(self):
...             self.priv = "private"
... 
>>> aI = cA()
>>> bI = cA()
>>> aI.pub; bI.pub
'public'
'public'
>>> cA.pub = "public2"
>>> aI.pub; bI.pub
'public2'
'public2'
>>> aI.pub = "public3"
>>> aI.pub; bI.pub
'public3'
'public2'
>>> # Oh no!

我的问题是:这是如何完成的(相关的实现细节是什么)?

以下是我的假设和推理。


重新启动一切并检查实例的命名空间,看起来它们每个都包含对 object 的直接引用pub,并且检查内存位置告诉我们它们确实指向同一个对象:

>>> aI = cA()
>>> bI = cA()
>>> dir(aI)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'priv', **'pub'**]
>>> dir(bI)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'priv', **'pub'**]
>>> id(aI.pub); id(bI.pub)
4466990384
4466990384

检查类本身的命名空间,我们pub在这里也看到:

如果aI并且bI确实包含对该对象的直接引用,那么对该对象的任何更改(创建新对象)都必须将新对象放在同一位置,以便 aI.pub 正确解析。但是,我们看到情况并非如此:

>>> id(cA.pub)
4466990384
>>> cA.pub = "public2 I'm making this longer to avoid interning effects"
>>> id(cA.pub)
4467260752
>>> id(aI.pub); id(bI.pub)
4467260752
4467260752

现在,由于我们没有修改任何aI内存,我们只能假设它pub实际上不dir包含对类变量的引用pub

我的假设(请确认/拒绝)是实例不包含任何实际将它们连接到类变量的东西,每个实例都有一个类字典,然后是一个字典,并且当访问类变量时会发生什么是本地解析失败,它会上升层次结构(下一行是类dict),然后解析引用并访问对象(引用到类→引用到对象→对象),即

cADict = {reference to pub object}

aIDict = {reference to priv object, to class}

aI实际上确实包含对 pub 对象的直接引用的替代方案将要求每次更新类实例时都必须遍历该类的所有实例并更新它们的 pub 引用 - 这是不切实际的)

对我的原作的跟进:看到 aspub实际上不在aI's 的命名空间中,为什么dir()说它在?

(我认为dir打印对象命名空间中所有引用的列表?)

标签: pythonpython-3.xclassnamespaces

解决方案


推荐阅读