翻译
原博客:https://sadh.life/post/builtins/#so-whats-a-builtin
如Python标准库文档所言:
Python 标准库非常庞大,所提供的组件涉及范围十分广泛,正如以下内容目录所显示的。这个库包含了多个内置模块 (以 C 编写),Python 程序员必须依靠它们来实现系统级功能,例如文件 I/O,此外还有大量以 Python 编写的模块,提供了日常编程中许多问题的标准解决方案。
显然,一篇博客无法覆盖Python标准库的所有内容,这篇博客对Python的内置(builtin)模块提供了一个简要的概述。
Python 内置功能存在于builtins
模块。
你需要了解L.E.G.B 规则。该规则定义了Python查找变量作用域的顺序。具体来说:
(译者注:简单来说,从里到外进行查找)
local scope(局部作用域)指的是当前函数或者当前类的作用域。每个函数调用或类实例化都会创建一个新的局部作用域,存放局部变量。
e.g
x = 11
print(x)
def some_function():
x = 22
print(x)
some_function()
print(x)
output:
11
22
11
注意到 some_function()
内 x = 22
定义了一个新的变量,该函数的局部名称空间(local namespace)定义了一个x
。在x = 22
后,该函数内访问x
(print(x)
) ,访问的都是该作用域的x
(22)。而离开函数some_function()
后,外部访问的x
是外部定义的`x。
Enclosing scope(封闭作用域)或称 nonlocal scope(非局部作用域):当前函数/类 所在的函数/类。说起来有点绕,直接看例子吧:
x = 11
def outer_function():
x = 22
y = 789
def inner_function():
x = 33
print('Inner x:', x)
print('Enclosing y:', y)
inner_function()
print('Outer x:', x)
outer_function()
print('Global x:', x)
output
Inner x: 33
Enclosing y: 789
Outer x: 22
Global x: 11
每个新函数/类都创建自己的本地作用域,独立于其外部环境。函数内部可以访问外部变量(print('Enclosing y:', y)
),但在本地作用域中创建的任何变量(x = 33
)都不会影响外部作用域。因此在内部函数内重新定义 x
为不会影响 外部或全局定义的x
。
但是,如果想影响外部的变量该怎么做?可以使用关键字nonlocal
告诉解释器,你不打算在本地定义新变量,而是修改封闭作用域中的变量:
def outer_function():
x = 11
def inner_function():
nonlocal x
x = 22
print('Inner x:', x)
inner_function()
print('Outer x:', x)
output:
Inner x: 22
Outer x: 22
(inner_function 通过nolocal x
的声明,告诉解释器这个x来自外层。)
Global scope(全局作用域)或称为module scope(模块作用域)指定义模块的顶级变量、函数和类的作用域。
“模块”是可以运行或导入的任何python文件或包。例如,time
是一个模块(你可以import time
),time.sleep()
是time
模块的全局作用域中定义的函数。
Python中的每个模块都有一些预定义的全局变量,例如__name__
和__doc__
,它们分别是模块的名称和模块的文档字符串。您可以在 REPL(Read-Evaluate-Print-Loop,Python解释器的功能) 中尝试此操作:
>>> print(__name__)
__main__
>>> print(__doc__)
None
>>> import time
>>> time.__name__
'time'
>>> time.__doc__
'This module provides various functions to manipulate time values.'
现在我们进入这个博客的主题 ——内置范围。
关于Python中的内置范围:
len
、range
和print
。如果需要,您可以通过导入模块builtins
并检查其中的方法:
>>> import builtins
>>> builtins.a # press <Tab> here
builtins.abs( builtins.all( builtins.any( builtins.ascii(
Python默认在全局名称空间__builtins__
暴露了内置模块,所以你可以直接访问__builtins__
,无需导入任何东西。
注意, __builtins__
是CPython的实现细节, Python的其他实现未必包含。因此import builtins
是最正确的访问内置模块的方法。(译者注:CPython是Python官方的实现,也有其他实现如Jython
)
可以用dir
列出所有内置变量。
print(dir(__builtins__))
(数了一下,有154个) 有很多,所以我们会将它们分成不同类型,逐个击破。