为什么不重新赋值给__builtins __.dict会影响新词典对象的创建?

Dan*_* B. 6 built-in python-3.x

一位同学问了一个关于覆盖内置类字典的问题,经过一番探讨后,我变得更加不确定.

采取内置的词典.我可以分配这个变量:

>>> dict=5
>>> dict
5
Run Code Online (Sandbox Code Playgroud)

现在,我已经失去了进入字典(这会不会像阴影在C++或者是不同的?),但我仍然能够通过访问类建宏 .dict.但我也可以覆盖它:

>>> __builtins__.dict = 6
>>> __builtins__.dict
6
Run Code Online (Sandbox Code Playgroud)

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

>>> stillDict = {'key': 'value'}
>>> stillDict
{'key': 'value'}
Run Code Online (Sandbox Code Playgroud)

那么为什么在我阴影之后这个班仍然"有效"呢?解释器如何知道我正在使用这个赋值创建一个字典,如何构建字典,因为它显然实际上并不需要__builtins__.dict

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

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

>>> a = dict()
>>> a.items
<built-in method items of dict object at 0x0000000002C97C08>
Run Code Online (Sandbox Code Playgroud)

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

>>> b = {}
>>> b.items
<built-in method items of dict object at 0x000000000288FC88>
Run Code Online (Sandbox Code Playgroud)

这导致后续......这两个仍然是"dict对象",是dict类只是使用构造函数来创建一个dict对象?一旦我隐藏了类,为什么我仍然可以访问内置方法?

Sim*_*ser 5

{'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
Run Code Online (Sandbox Code Playgroud)

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

正如你提到的,的含义dict已经改变。


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

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