一般来说,python 中包含如下四种变量作用域
- local:函数本地作用域
- enclosed:闭包作用域
- global:全局作用域
- built-in:内建类型作用域
当 python 解析器遇到某一个变量时,它就会以如下优先级确定这个变量定义在哪里。我们可以看出,这遵循了一种 “自发现位置开始由内到外” 的规则。
local > enclosed > global > built-in
1. local 作用域
def foo():
x = 1
print(locals())
y = 2
print(locals())
foo()
图中的 x 和 y 都是 local 作用域的变量。
他们只存在于 foo 函数中,这意味着当 foo 函数执行结束时,他们就无法被再次使用,并且可能会被垃圾回收掉(除非他们成为闭包变量 - enclosed)
并且要注意的是,每当 foo 函数被执行一次时,x 和 y 都会被创建一次,包括每次递归。
注意到代码中的 print(locals()) 部分,他可以实时的查看到当前作用域中有多少本地变量。上面的函数输出为
{'x': 1}
{'x': 1, 'y': 2}
2. enclosed 作用域
def outer():
x = 1
y = 'b'
def inner():
return x, y
return inner
i = outer()
print(i())
print(i.__closure__)
这是一个典型的闭包定义,在 inner 中引用了外层函数的局部变量 x 和 y。
这样的结果是,x 和 y 将一直维持在内存中,供 inner 函数使用。
注意到 print(i.__closure__) 这一行代码,这是一种获取一个函数在使用的闭包变量的途径。
上面的函数输出如下,我们可以看到,这个函数对一个 int 类型的变量和一个 str 类型的变量维持了引用(即 x 和 y)
(1, 'b')
(<cell at 0x1065633a0: int object at 0x1064000f0>, <cell at 0x1065625f0: str object at 0x10651f6b0>)
2.1 回顾作用域的强度比较
回到最开始的作用域强度讨论,由于 local 强于 enclosed,下面的代码将使用 inner 函数的本地变量,而非闭包变量
def outer():
x = 1
y = 'b'
def inner():
x = 'b'
y = 2
return x, y
return inner
i = outer(
Python变量作用域及存储机制介绍

最低0.47元/天 解锁文章
2142

被折叠的 条评论
为什么被折叠?



