Python 有没有一种方法可以获取带有非局部变量的dict对象?

Python 有没有一种方法可以获取带有非局部变量的dict对象?,python,python-3.x,Python,Python 3.x,我想知道,Python中是否有一个函数可以返回包含封闭函数中使用的非局部变量的dict对象?如vars()或locals()用于局部变量,或globals()用于全局变量 更新: 正如Bjorn所指出的,嵌套函数中实际使用的非局部变量包含在local列表中。关于3.2.3,以下代码 >>> def func1(): ... x=33 ... def func2(): ... # Without the next line prints {

我想知道,Python中是否有一个函数可以返回包含封闭函数中使用的非局部变量的dict对象?如
vars()
locals()
用于局部变量,或
globals()
用于全局变量

更新: 正如Bjorn所指出的,嵌套函数中实际使用的非局部变量包含在
local
列表中。关于3.2.3,以下代码

>>> def func1():
...     x=33
...     def func2():
...             # Without the next line prints {}
...             print(x)
...             print(locals())
...     func2()
... 
>>> func1()

返回
{'x':33}
没有内置的
非局部变量()
,但您可以自己创建一个:

def nonlocals():
    import inspect
    stack = inspect.stack()
    if len(stack) < 3: return {}
    f = stack[2][0]
    res = {}
    while f.f_back:
        res.update({k:v for k,v in f.f_locals.items() if k not in res})
        f = f.f_back
    return res
def nonlocals():
进口检验
stack=inspect.stack()
if len(stack)<3:返回{}
f=堆栈[2][0]
res={}
当f.f_返回时:
res.update({k:v代表k,v在f.f_locals.items()中,如果k不在res})
f=f.f_后
返回res
如果我在你的程序上运行它,我会得到:

{'func2': <function func1.<locals>.func2 at 0x0000000002A03510>, 'x': 33}
{'func2':,'x':33}

公认的答案非常非常错误-
f_back
给出的是调用方,而不是词法上的父范围

Python是词汇范围的,而不是动态范围的

可以使用所述方法完成所需操作:


快速测试表明,在Python 3.3中,
nonlocal
名称包含在
locals
中,您使用的是什么版本?不,只有在本地使用时才包含在locals中…@delnan我使用的是3.2.3。在这个版本中,
locals()
如果在嵌套函数中使用,则返回
{}
。我怀疑您的测试有缺陷。
locals()
只返回局部变量和自由变量。如果您的内部函数中有一个非本地函数(即您没有使用它),则
locals()
不会列出它。谢谢您的回答!在IronPython中,如果没有命令行选项
-X:FullFrames
,这将不起作用,因为这会影响性能,应该只用于调试。一般来说,Python的实现不必支持堆栈帧检查。不要使用它,这是非常错误的!!它使用动态范围而不是词汇范围查找变量!!嗯。。你不是在用上面的
.f_back
吗(链接的答案没有这个功能)。@thebjorn:是的,很好。链接的答案不需要这样做,因为它的调用者已经调用了
inspect.currentframe()
,并提供了它的起始堆栈帧,所以答案不需要这样做。但是,在这里,我没有提供起始
,因此我需要通过检查堆栈来获得它。这与变量查找机制完全不同。我在这里没有做的是使用
.f\u back
链动态查找变量(请参阅接受答案中循环内的
.f\u back
),这就是答案的问题。啊,我明白了。您是否也可以解决原始问题,即获取不在
globals()
locals()
中的所有词汇范围变量的dict?这意味着,从OPs代码返回
{'x':33}
,而不需要通过使用变量(这里通过调用print)或使用非局部语句声明它来将变量拉入局部变量?@thebjorn:不幸的是,据我所知,这是不可能的,因为封闭函数不存储对其封闭函数的引用。它只直接存储对包含闭包变量的单元格的引用,这仅适用于闭包中的变量。事实上,如果变量不在闭包中,那么此时它们甚至可能不存在。(换句话说,这需要Python程序无限期地存储自己的执行历史记录,永远不要丢弃它,因为以后可能有人决定从某个死帧中查找变量。)
def nonlocals():
    import inspect
    caller = inspect.currentframe().f_back
    return {k: v for k, v in caller.f_locals.items() if k in caller.f_code.co_freevars}