一、作用域概览
在Python中,作用域定义了变量名在程序中的可见性和可访问范围。主要分为以下三种类型:
- 全局作用域(Global Scope) 全局作用域是指在整个脚本或模块中都可见的变量。在函数外部定义的变量默认属于全局作用域,可以在文件的任何位置被引用:
global_var = "This is a global variable."
def func():
print(global_var) # 在此函数内部可以访问全局变量
- 局部作用域(Local Scope) 局部作用域仅限于函数内部。在函数内部定义的变量只在该函数内部有效,超出函数边界则无法访问:
def local_func():
local_var = "This is a local variable."
print(local_var)
local_func() # 输出: This is a local variable.
print(local_var) # 报错:NameError: name 'local_var' is not defined
- 嵌套作用域(Enclosing Scope/Nested Scope) 当一个函数内包含另一个函数时,形成了嵌套作用域。内部函数可以访问外部函数的变量,但不能直接修改非全局的外部变量,除非使用 nonlocal 关键字:
def outer_func():
outer_var = "Outer Variable"
def inner_func():
nonlocal outer_var # 使用nonlocal关键字声明访问外层作用域的变量
outer_var += " (modified by inner)"
print(outer_var)
inner_func()
outer_func() # 输出: Outer Variable (modified by inner)
二、LEGB规则
理解Python作用域的一个重要工具是LEGB规则,即:
- Local:局部作用域,当前函数内部定义的变量。
- Enclosing:嵌套作用域,包围当前函数的最近一层非全局作用域,通常涉及闭包。
- Global:全局作用域,当前模块的顶层定义的变量。
- Built-in:内置作用域,Python预定义的内置名称,如 len, print 等。
- Python在查找变量时会遵循LEGB规则从内到外依次搜索。
三、修改全局变量与global关键字
在函数内部若要修改全局变量的值,需要明确指定该变量为全局变量:
global_var = 10
def modify_global():
global global_var # 声明全局变量
global_var += 5
modify_global()
print(global_var) # 输出:15
使用注意事项:
- 避免过度使用全局变量:尽量减少全局变量的使用,因为它们在整个模块甚至程序中都可见,可能导致命名冲突、代码难以理解和维护等问题。
- 函数参数作为作用域的一种形式:函数参数在函数调用时创建,并在函数执行期间拥有局部作用域。修改参数通常不会影响到调用者传入的原始对象,除非它是可变类型(如列表、字典)。
- 初始化与引用陷阱:在定义函数时,如果将可变对象作为默认参数值,由于默认参数在函数定义时只计算一次,所有函数调用共享同一份默认值,可能会引发意外行为。应避免这种情况,或者使用None或其他方式来确保每次调用函数时都能得到新的对象实例。
- 注意函数内部临时变量的影响范围:函数内部定义的临时变量仅在函数执行过程中存在,当函数结束时,这些变量会被回收,因此不能在函数外部直接访问。