(转)通过内置对象理解 Python(一)


原文:https://qiwsir.github.io/2021/11/03/python-builtins-first/

https://qiwsir.github.io/-----------------其他章节

如果你已经对 Python 有了初步的了解,比如阅读过《Python 大学使用教程》或者《跟老齐学 Python:轻松入门》,亦或者学习过老齐在 CSDN 等平台上发布的在线课程(参考:www.itdiffer.com),再阅读本文,会帮助你更深刻立即 Python 语言的特点,掌握 Python 语言的使用方法。

了解内置对象

Python 的内置对象是指 builtins 模块中所有的内容。

为了更好地理解这一点,需要了解一下 L.E.G.B. 规则。

L.E.G.B. 规则定义了在Python中查找的变量所在的作用域顺序 ,分别是:

  • Local scope(局部作用域,或本地作用域)
  • Enclosing (or nonlocal) scope(闭包作用域,或非局部作用域)
  • Global scope(全局作用域)
  • Builtin scope(内置作用域)

注:有关作用域的详细解释,请参阅 www.itdiffer.com 中的有关文章

局部作用域

创建了函数或类之后,每次调用它们,在其中便创建了局部作用域。例如:

1
2
3
4
5
6
7
8
9
10
x = 11
print(x)

def some_function():
x = 22
print(x)

some_function()

print(x)

运行这段代码会输出以下内容:

1
2
3
11
22
11

下面分析执行过程:在 some_function() 函数中中定义了一个新变量 x = 22 ,它位于函索所定义的局部命名空间**中。之后,只要在函数内使用 x ,它指的就是在局部作用域内的那个 x 。若访问 some_function() 函数之外的 x 时,则指的是在 x = 11 中定义的那个x 。

闭包作用域

闭包作用域是嵌套函数中出现的作用域,还是用一个例子来解释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
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)

它的输出是:

1
2
3
4
Inner x: 33
Enclosing y: 789
Outer x: 22
Global x: 11

它本质含义是,每个函数或类创建自己的本地作用域,与外部环境分离。如果在本地作用域中访问外部变量,是可行的;但是在本地作用域中创建的任何变量都不会影响外部的作用域。所以在内部函数中重新赋值 x = 33 并不影响外部所定义的 x 的值。

但是,如果我想影响外部作用域,怎么办?

为此,可以在使用关键词 nonlocal ,让它来告诉解释器:你不是要在局部作用域中定义一个新变量,而是要修改闭包作用域(外围作用域)中的变量。

1
2
3
4
5
6
7
8
9
10
def outer_function():
x = 11

def inner_function():
nonlocal x
x = 22
print('Inner x:', x)

inner_function()
print('Outer x:', x)

打印结果如下:

1
2
Inner x: 22
Outer x: 22

全局作用域

全局作用域指定义模块中的顶级变量、函数和类的作用域。

“模块”是任何可以运行或导入的 Python 文件或包。 例如: time 是标准库中的一个模块(用 import time 导入),而 time.sleep() 是定义在 time 模块的全局作用域中的函数。

Python 中的每个模块都有一些预定义的全局变量,例如 __name__ 和 __doc__,它们分别引用模块的名称和模块的文档字符串。

1
2
3
4
5
6
7
8
9
>>> print(__name__)
__main__
>>> print(__doc__)
None
>>> import time
>>> time.__name__
'time'
>>> time.__doc__
'This module provides various functions to manipulate time values.'

内置作用域

现在我们进入本文的主题——内置作用域。

关于 Python 的内置作用域,以下两个方面需要了解:

  • 它是定义 Python 所有顶级函数(或内置函数)的作用域,比如 len 、range 和 print 。
  • 当一个变量在局部、闭包或全局作用域中找不到时,Python 会在内置作用域中寻找它。

可以导入 builtins 模块,并查看该作用域中的所有对象:

1
2
3
>>> import builtins
>>> dir(builtins)
# 显示内容从略

由于某些未知原因,Python 在全局命名空间中默认将内置模块显示为 __builtins__ 。 所以也可以直接访问 __builtins__ ,而不需要导入任何东西。 注意, __builtins__ 是用 CPython 实现的,其他 Python 实现可能没有它。import builtins 是访问内置模块的最正确的方式。