简体   繁体   English

Python3 `builtins` 并不总是 `__builtins__`

[英]Python3 `builtins` is not always `__builtins__`

I was putting this idea How to make a cross-module variable?我提出了这个想法如何制作跨模块变量? in action for python3.在 python3 中运行。 And was lazy enough to use the variable __builtins__ instead of the module builtins .并且懒得使用变量__builtins__而不是模块builtins Which should make no difference because:这应该没有区别,因为:

# file spam.py:
import builtins
print (builtins is __builtins__)
print (id(builtins))
print (id(__builtins__))

This is when it gets funny: builtins is not __builtins__ when imported:这是有趣的时候: builtins函数在导入时不是__builtins__

$ python3 spam.py 
True
140598001743336
140598001743336

$ python3 -c 'import spam'
False
139755426543080
139755426520904

Does anyone know what happens?有谁知道会发生什么?

(A comment on the given page mentions " __builtins__ is a CPython peculiarity, you really shouldn't use it", but I'm being curious...) (给定页面上的评论提到“ __builtins__是 CPython 的特性,你真的不应该使用它”,但我很好奇......)

I don't really know why, but from article我真的不知道为什么,但从文章

frame globals have a __builtins__ variable (builtins dictionary, or builtins module when __name__ equals __main__ )框架全局变量有一个__builtins__变量(当__name__等于__main__时,内置字典或内置模块)

so in your first case ( __name__ == __main__ ) and you get __builtins__ as builtins module, but in the second case ( __name__ != __main__ ) __builtins__ is a dict instance and from docs :所以在你的第一种情况下( __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. __builtins__的值通常是这个模块或者这个模块的__dict__属性的值。

Test测试

With slightly modified spam.py稍微修改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__))

we will get something like我们会得到类似的东西

$ python3 spam.py 
<class 'module'>
True
2345652270648
2345652270648

$ python3 -c 'import spam'
<class 'dict'>
True
2770543697736
2770543697736

Conclusion结论

As you & @chepner have already noticed __builtins__ is an implementation detail that can be changed, so we shouldn't rely on it, especially on it being a builtins module/ builtins.__dict__ object.正如你和@chepner 已经注意到__builtins__是一个可以改变的实现细节,所以我们不应该依赖它,尤其是它是一个builtins module/ builtins.__dict__对象。

For CPython implementation,对于 CPython 实现,

in the __main__ module: __builtins__ is builtins .__main__模块中: __builtins__ is builtins
in other module: __builtins__ is builtins.__dict__在其他模块中: __builtins__ is builtins.__dict__

Refs:参考:
https://docs.python.org/3/reference/executionmodel.html#builtins-and-restricted-executionhttp://mathamy.com/whats-the-deal-with-builtins-vs-builtin.html https://docs.python.org/3/reference/executionmodel.html#builtins-and-restricted-executionhttp://mathamy.com/whats-the-deal-with-builtins-vs-builtin.html

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM