为什么重新分配给 __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()
(您可以影响)。
一个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()
(您可以影响)。