2026-10-20 16:54:41
Python变量作用域是编程中容易混淆但至关重要的概念,主要涉及局部变量、全局变量、自由变量和内置变量。以下是对这些作用域的清晰梳理和关键规则总结:
一、变量作用域的分类局部变量(Local)
定义位置:函数内部定义的变量或函数形参。
作用范围:仅在定义它的函数内有效。
示例:
def func(): x = 10 # 局部变量全局变量(Global)
定义位置:模块(.py文件)顶层定义的变量。
作用范围:整个模块内有效,但需通过global关键字在函数内修改。
示例:
g = "global" # 全局变量def func(): print(g) # 可直接访问自由变量(Enclosing/Nonlocal)
定义位置:嵌套函数中,外层函数定义但非全局的变量,且被内层函数引用。
作用范围:通过闭包(Closure)实现跨作用域访问,需用nonlocal修改。
示例:
def outer(): e = "enclose" # 自由变量 def inner(): print(e) # 引用自由变量 return inner内置变量(Builtin)
定义位置:Python内置模块(如builtins)中的变量(如len、print)。
作用范围:默认全局可用,除非被同名变量覆盖。
Python按以下顺序查找变量(优先级从高到低):
示例解析:
import builtinsbuiltins.b = "builtins"g = "global"def outer(o1): e = "enclose" def inner(i1): print(i1, o1, e, g, b) # 依次查找:Local(i1) → Enclosing(o1,e) → Global(g) → Builtin(b) return innerfun = outer("o1_param")fun("i1_param") # 输出: i1_param o1_param enclose global builtins三、关键问题与解决方案局部作用域中修改全局/自由变量
问题:直接赋值会创建局部变量,而非修改外部变量。
解决:
用global声明全局变量:
g = "global"def func(): global g g = "modified" # 修改全局变量用nonlocal声明自由变量:
def outer(): e = "enclose" def inner(): nonlocal e e = "modified" # 修改外层函数的变量 return inner变量名冲突风险
若局部变量与全局变量同名,局部作用域内会屏蔽全局变量(除非用global声明)。
示例:装饰器中的自由变量
def logger(func): count = 0 # 自由变量 def wrapper(*args): nonlocal count count += 1 print(f"函数被调用 {count} 次") return func(*args) return wrapper@loggerdef greet(): print("Hello")greet() # 输出: 函数被调用 1 次 n Hello通过明确作用域规则和合理使用global/nonlocal,可以高效管理变量作用域,避免常见陷阱。