Skip to main content
 首页 » 编程设计

Python3 `builtins` 并不总是 `__builtins__`

2024年08月14日30cmt

我把这个想法放在了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__ 对象。