变量的作用域决定了变量在程序中的可见性和生命周期。
在Python中,变量的作用域有以下几种:
- 局部作用域(当前函数内部)
- 嵌套作用域(外层函数)
- 全局作用域(模块级别)
- 内置作用域(Python的内置函数和内置变量)
局部作用域
函数内的变量通常称为局部变量,只有该函数内部可见,函数外无法访问,函数执行结束时,该变量会被销毁。
示例如下:
def access_local():
v = 100 # 局部变量
print(v)
# 输出: 100
access_local()
# 以下语句会报错,因为v是access_local()的内部变量,外部不可见
# print(v)
嵌套作用域
在 Python 中,可以在一个函数(外部函数)中定义另一个函数(内部函数),内部函数可以访问外部函数的变量,外部函数的变量也称为嵌套作用域变量。外部函数变量仅对外部函数内部可见,外部函数外不可访问,因为外部函数和内部函数都可以访问该变量,所以其生命周期会受到这两个函数的共同影响。
示例如下:
def outer_func():
def inner_func():
print(v) # 内部函数可以访问外部函数的变量
v = 100
inner_func()
# 输出: 100
outer_func()
全局作用域
在函数外定义的变量称为全局变量,在整个模块(或文件内)可见,全局变量在整个程序运行结束后销毁。 如果模块外部要访问模块内部定义的全局变量,常用的方法是通过 import 导出这个模块到外部。
示例如下:
v = 100 # 全局变量
def access_global():
print(v)
# 输出: 100
access_global()
内置作用域
内置作用域的函数和变量在任何模块都可以随时访问,例如,常见的内置函数有 len()、print() 等,常见的内置变量有 None、True、False等。
有一个重要的内置变量是需要注意的,它是 __name__,当 Python 文件作为脚本直接运行时,__name__ 的值为 '__main__',当 Python 文件作为模块被其他文件导入时,__name__ 的值为模块名称,因此,__name__ 通常用于区分 Python 文件是直接运行还是被外部引用。
示例如下:
if __name__ == '__main__':
# 输出: __main__
print(__name__)
查找变量的顺序
访问一个变量时,Python 会按照以下顺序查找:局部作用域 -> 嵌套作用域 -> 全局作用域 -> 内置作用域。
这意味着,如果不同作用域存在重名的变量,Python 会优先访问先找到的变量,其他变量会被屏蔽。需要注意的是,虽然这种情况,Python 不会报错,但是,在实际编码中,不同范围的变量尽量不要重名。
示例如下:
x = 200
def access_local_x():
x = 300
print(x)
# 输出: 300
access_local_x()
函数内修改全局变量
函数内是可以访问全局变量的,但是默认情况下,不能修改全局变量。如果要修改全局变量,可以借助 global 关键字。
示例如下:
y = 1000
def modify_global():
global y # 声明此处使用的变量 y 是全局变量
y = 2000
print(y) # 输出: 1000
modify_global()
print(y) # 输出: 2000
内部函数中修改外部函数的变量
内部函数可以访问外部函数的变量,但是默认情况下,不能修改该变量。如果要修改外部函数的变量,可以借助 nonlocal 关键字。
示例如下:
def outer_function():
v = 100 # 外部函数的变量
def inner_function():
nonlocal v # 声明此处使用的 v 是外部函数的变量
v = 200 # 修改外部函数的变量
print(v) # 输出: 100
inner_function()
print(v) # 输出: 200
outer_function()