如何检查具有给定名称的变量是否是非本地的?
How to check if a variable with a given name is nonlocal?
给定堆栈帧和变量名,如何判断该变量是否为非本地变量?示例:
import inspect
def is_nonlocal(frame, varname):
# How do I implement this?
return varname not in frame.f_locals # This does NOT work
def f():
x = 1
def g():
nonlocal x
x += 1
assert is_nonlocal(inspect.currentframe(), 'x')
g()
assert not is_nonlocal(inspect.currentframe(), 'x')
f()
检查框架的代码对象的 co_freevars
,它是代码对象使用的闭包变量名称的元组:
def is_nonlocal(frame, varname):
return varname in frame.f_code.co_freevars
请注意,这是特定的闭包变量,即 nonlocal
语句查找的那种变量。如果你想包含所有非本地变量,你应该检查 co_varnames
(内部范围内未使用的局部变量)和 co_cellvars
(内部范围内使用的局部变量):
def isnt_local(frame, varname):
return varname not in (frame.f_code.co_varnames + frame.f_code.co_cellvars)
此外,不要将 co_names
与当前错误记录的内容混淆。 inspect
文档说 co_names
用于局部变量,但 co_names
是一种 "everything else" bin。它包括全局名称、属性名称和导入中涉及的几种名称 - 大多数情况下,如果预计执行实际上需要名称的字符串形式,它会进入 co_names
.
给定堆栈帧和变量名,如何判断该变量是否为非本地变量?示例:
import inspect
def is_nonlocal(frame, varname):
# How do I implement this?
return varname not in frame.f_locals # This does NOT work
def f():
x = 1
def g():
nonlocal x
x += 1
assert is_nonlocal(inspect.currentframe(), 'x')
g()
assert not is_nonlocal(inspect.currentframe(), 'x')
f()
检查框架的代码对象的 co_freevars
,它是代码对象使用的闭包变量名称的元组:
def is_nonlocal(frame, varname):
return varname in frame.f_code.co_freevars
请注意,这是特定的闭包变量,即 nonlocal
语句查找的那种变量。如果你想包含所有非本地变量,你应该检查 co_varnames
(内部范围内未使用的局部变量)和 co_cellvars
(内部范围内使用的局部变量):
def isnt_local(frame, varname):
return varname not in (frame.f_code.co_varnames + frame.f_code.co_cellvars)
此外,不要将 co_names
与当前错误记录的内容混淆。 inspect
文档说 co_names
用于局部变量,但 co_names
是一种 "everything else" bin。它包括全局名称、属性名称和导入中涉及的几种名称 - 大多数情况下,如果预计执行实际上需要名称的字符串形式,它会进入 co_names
.