如何获取Python作用域内所有可用变量?含嵌套函数场景
如何在嵌套的inner函数中获取外层outer函数的变量?
先看你的代码:
var_global = "global" def outer() : var_outer = "outer" def inner() : var_inner = "inner" # 如何在此处获取所有可用变量(应包含var_inner、var_outer、var_global)? print("inner", locals(), globals()) return inner outer()()
执行后你会发现,locals()只返回{'var_inner': 'inner'},globals()能拿到全局的var_global,但var_outer既不在局部也不在全局里——这是因为var_outer是外层outer函数的局部变量,当inner引用它时,它会变成自由变量(free variable),被存储在闭包的cell结构中,不属于locals()或globals()的覆盖范围。
下面给你两种实用的解决方法:
方法一:用inspect模块直接获取闭包变量
Python的inspect模块专门提供了处理闭包变量的工具,getclosurevars函数可以一次性拿到闭包的全局变量、自由变量等信息,用法很简单:
import inspect var_global = "global" def outer() : var_outer = "outer" def inner() : var_inner = "inner" # 提取所有类型的变量并合并 closure_info = inspect.getclosurevars(inner) all_available_vars = { **closure_info.globals, # 全局变量(比如var_global) **closure_info.nonlocals, # 外层函数的变量(比如var_outer) **locals() # 当前inner的局部变量(比如var_inner) } print("所有可用变量:", all_available_vars) return inner outer()()
执行后会输出:
所有可用变量: {'var_global': 'global', 'var_outer': 'outer', 'var_inner': 'inner'}
方法二:手动访问函数的闭包属性(无需额外模块)
如果你不想导入inspect,可以直接访问函数的内置属性来获取自由变量:
inner.__code__.co_freevars:存储了外层自由变量的名称元组inner.__closure__:存储了对应自由变量的cell对象,通过cell_contents可以拿到变量的值
代码示例:
var_global = "global" def outer() : var_outer = "outer" def inner() : var_inner = "inner" # 构建自由变量的字典 free_vars = {} if inner.__closure__: free_vars = dict( zip(inner.__code__.co_freevars, [cell.cell_contents for cell in inner.__closure__]) ) # 合并所有变量 all_available_vars = {**globals(), **free_vars, **locals()} print("所有可用变量:", all_available_vars) return inner outer()()
执行后同样能得到包含三个变量的结果。
内容的提问来源于stack exchange,提问作者Mitar
相关产品推荐
相关产品推荐

