获取当前范围内所有变量及其值的字典

Rom*_*kov 33 python

请考虑以下代码段:

globalVar = 25

def myfunc(paramVar):
    localVar = 30
    print "Vars: {globalVar}, {paramVar}, {localVar}!".format(**VARS_IN_SCOPE)

myfunc(123)
Run Code Online (Sandbox Code Playgroud)

VARS_IN_SCOPE我之后的字典在哪里包含globalVar,paramVar以及localVar其他内容.

我想基本上能够引用字符串中当前范围内的所有变量.因此预期的产出将是:

Vars: 25, 123, 30

我可以通过传递**dict(globals().items() + locals().items())来实现这一目标format().这总是正确的还是这个表达式会错误处理的一些极端情况?

改写以澄清问题.

Ale*_*lli 35

在你做的时候合并两个dicts的最佳方法是(当地人重写全局变量)dict(globals(), **locals()).

缺少合并全局和本地的方法是(a)内置(我想这是故意的,即你不认为内置是"变量"......但是,它们可能是,如果你这样选择! - ),和(b)如果你在一个很嵌套函数,任何变量是局部的封闭功能(没有真正好的方式来获得一个字典与所有这些,再加上-只有那些在嵌套函数显式访问,即"免费其变量"无论如何都以封闭中的细胞存活".

我想这些问题对你的预期用途没什么大不了的,但你确实提到了"极端情况";-).如果你需要覆盖它们,有办法让内置插件(这很容易)和(不那么容易)的所有单元格(从封闭您明确提到在嵌套函数函数的变量- thefunction.func_code.co_freevars得到的名字,thefunction.func_closure以获取cell_contents每个单元格上的单元格以获得其值).(但是,请记住,这些只是封装在嵌套函数代码中显式访问的函数的变量!).


Mar*_*off 8

这样做符合你的意图吗?

d = dict(globals())
d.update(locals())
Run Code Online (Sandbox Code Playgroud)

如果我正确地阅读文档,为您打造的副本globals()字典,那么你覆盖所有副本从插入新的条目locals()字典(因为locals()必须有自己范围内的喜好,反正).


我没有任何可进行正确的函数返回的变量的完整字典中的范围运气通话 功能.这是代码(我只使用pprint来很好地格式化输出SO):

from pprint import *

def allvars_bad():
    fake_temp_var = 1
    d = dict(globals())
    d.update(locals())
    return d

def foo_bad():
    x = 5
    return allvars_bad()

def foo_good():
    x = 5
    fake_temp_var = "good"
    d = dict(globals())
    d.update(locals())
    return d

pprint (foo_bad(), width=50)
pprint (foo_good(), width=50)
Run Code Online (Sandbox Code Playgroud)

和输出:

 {'PrettyPrinter': <class pprint.PrettyPrinter at 0xb7d316ec>,
 '__builtins__': <module '__builtin__' (built-in)>,
 '__doc__': None,
 '__file__': 'temp.py',
 '__name__': '__main__',
 '__package__': None,
 'allvars_bad': <function allvars_bad at 0xb7d32b1c>,
 'd': <Recursion on dict with id=3084093748>,
 'fake_temp_var': 1,
 'foo_bad': <function foo_bad at 0xb7d329cc>,
 'foo_good': <function foo_good at 0xb7d32f0c>,
 'isreadable': <function isreadable at 0xb7d32c34>,
 'isrecursive': <function isrecursive at 0xb7d32c6c>,
 'pformat': <function pformat at 0xb7d32bc4>,
 'pprint': <function pprint at 0xb7d32b8c>,
 'saferepr': <function saferepr at 0xb7d32bfc>}
{'PrettyPrinter': <class pprint.PrettyPrinter at 0xb7d316ec>,
 '__builtins__': <module '__builtin__' (built-in)>,
 '__doc__': None,
 '__file__': 'temp.py',
 '__name__': '__main__',
 '__package__': None,
 'allvars_bad': <function allvars_bad at 0xb7d32b1c>,
 'd': <Recursion on dict with id=3084093884>,
 'fake_temp_var': 'good',
 'foo_bad': <function foo_bad at 0xb7d329cc>,
 'foo_good': <function foo_good at 0xb7d32f0c>,
 'isreadable': <function isreadable at 0xb7d32c34>,
 'isrecursive': <function isrecursive at 0xb7d32c6c>,
 'pformat': <function pformat at 0xb7d32bc4>,
 'pprint': <function pprint at 0xb7d32b8c>,
 'saferepr': <function saferepr at 0xb7d32bfc>,
 'x': 5}
Run Code Online (Sandbox Code Playgroud)

请注意,在第二个输出中,我们已经覆盖fake_temp_var,并且存在x; 第一个输出只包括范围内的本地变量allvars_bad.

因此,如果要访问完整的变量范围,则不能将locals()放在另一个函数中.


我怀疑有某种框架对象,我只是没有(知道在哪里)寻找它.

这符合您的规范,我相信:

def allvars_good(offset=0):
    frame = sys._getframe(1+offset)
    d = frame.f_globals
    d.update(frame.f_locals)
    return d


def foo_good2():
    a = 1
    b = 2
    return allvars_good()
Run Code Online (Sandbox Code Playgroud)

- >

{'PrettyPrinter': <class pprint.PrettyPrinter at 0xb7d6474c>,
 '__builtins__': <module '__builtin__' (built-in)>,
 '__doc__': None,
 '__file__': 'temp.py',
 '__name__': '__main__',
 '__package__': None,
 'a': 1,
 'allvars_bad': <function allvars_bad at 0xb7d65b54>,
 'allvars_good': <function allvars_good at 0xb7d65a04>,
 'b': 2,
 'foo_bad': <function foo_bad at 0xb7d65f44>,
 'foo_good': <function foo_good at 0xb7d65f7c>,
 'foo_good2': <function foo_good2 at 0xb7d65fb4>,
 'isreadable': <function isreadable at 0xb7d65c6c>,
 'isrecursive': <function isrecursive at 0xb7d65ca4>,
 'pformat': <function pformat at 0xb7d65bfc>,
 'pprint': <function pprint at 0xb7d65bc4>,
 'saferepr': <function saferepr at 0xb7d65c34>,
 'sys': <module 'sys' (built-in)>}
Run Code Online (Sandbox Code Playgroud)