为什么重新分配给 __builtins__.dict 不会影响新字典对象的创建?

Why doesn't re-assignment to __builtins__.dict affect creation of new dictionary objects?

一个class朋友问了一个关于覆盖内置classdict的问题,经过一番摸索,我变得更加不确定。

使用内置字典。我可以分配这个变量:

>>> dict=5
>>> dict
5

现在我无法访问 dict(这会像 C++ 中的阴影一样还是不同?)但我仍然可以通过 builtins[=40= 访问 class ].dict。但我也可以覆盖它:

>>> __builtins__.dict = 6
>>> __builtins__.dict
6

但即使这样做也不会破坏 class 本身:

>>> stillDict = {'key': 'value'}
>>> stillDict
{'key': 'value'}

那为什么 class 在我隐藏它之后仍然 "work"?解释器如何知道我正在用这个赋值制作字典,以及字典是如何构造的,因为它显然实际上不需要 __builtins__.dict?

编辑 更进一步,西蒙的回答说这是因为我正在创建字典文字...

在覆盖之前,我可以这样做:

>>> a = dict()
>>> a.items
<built-in method items of dict object at 0x0000000002C97C08>

覆盖dict和__builtins__.dict后,我可以这样做:

>>> b = {}
>>> b.items
<built-in method items of dict object at 0x000000000288FC88>

这导致后续... 这两个还是"dict objects",难道dictclass只是用构造函数做了一个dict对象?为什么在隐藏 class 后仍然可以访问内置方法?

{'key': 'value'} 是一个字典文字,因此它继续具有生成字典的行为。 Python不用再去查dict是什么意思——跳过这一步,直接生成字节码构造字典:

>>> def f(): {'a': 3}
>>> import dis
>>> dis.dis(f)
  1           0 BUILD_MAP                1
              3 LOAD_CONST               1 (3)
              6 LOAD_CONST               2 ('a')
              9 STORE_MAP
             10 POP_TOP
             11 LOAD_CONST               0 (None)
             14 RETURN_VALUE

在字节码中,它继续像以前一样使用 BUILD_MAP(即,它根据您编写的代码构建映射/字典)。

dict 的意思已经按照你说的改变了。


关于后续问题:您没有隐藏词典 class / type - 您只是更改了 dict 的含义。你不能带走字典类型,Python 在使用字典文字时生成它(例如,{})。

一旦你有了一个类型为 dict 的对象,你就可以访问它的方法(比如 items())——只是你使用语法构造了它(你不能影响它)而不是调用 dict()(您可以影响)。