我把这个想法放在了How to make a cross-module variable?在 python3 中。 并且懒得使用变量 __builtins__ 而不是模块 builtins。这应该没有什么区别,因为:
# file spam.py:
import builtins
print (builtins is __builtins__)
print (id(builtins))
print (id(__builtins__))
有趣的是:builtins 在导入时不是 __builtins__:
$ python3 spam.py
True
140598001743336
140598001743336
$ python3 -c 'import spam'
False
139755426543080
139755426520904
有人知道怎么回事吗?
(给定页面上的评论提到“__builtins__ 是 CPython 的特性,你真的不应该使用它”,但我很好奇......)
请您参考如下方法:
我真的不知道为什么,但是来自 article
frame globals have a
__builtins__variable (builtins dictionary, or builtins module when__name__equals__main__)
所以在你的第一种情况下 (__name__ == __main__) 你得到 __builtins__ 作为 builtins 模块,但在第二种情况下 (__name__ != __main__) __builtins__ 是一个 dict 实例,来自 docs :
The value of
__builtins__is normally either this module or the value of this module’s__dict__attribute.
测试
略微修改了spam.py
import builtins
if __name__ == '__main__':
print(type(__builtins__))
print(__builtins__ is builtins)
print(id(builtins))
print(id(__builtins__))
else:
print(type(__builtins__))
print(__builtins__ is builtins.__dict__)
print(id(builtins.__dict__))
print(id(__builtins__))
我们会得到类似的东西
$ python3 spam.py
<class 'module'>
True
2345652270648
2345652270648
$ python3 -c 'import spam'
<class 'dict'>
True
2770543697736
2770543697736
结论
正如您和@chepner 已经注意到的那样,__builtins__ 是一个可以更改的实现细节,因此我们不应该依赖它,尤其是当它是一个builtins 时module/builtins.__dict__ 对象。
