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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1041639/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-03 21:20:47  来源:igfitidea点击:

Get a dict of all variables currently in scope and their values

python

提问by Roman Starkov

Consider this snippet:

考虑这个片段:

globalVar = 25

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

myfunc(123)

Where VARS_IN_SCOPEis the dict I'm after that would contain globalVar, paramVarand localVar, among other things.

VARS_IN_SCOPE我所追求的 dict在哪里,其中包含globalVar,paramVarlocalVar

I'd like to basically be able to reference all the variables that are currently in scope inside the string. Hence the expected output would be:

我希望基本上能够引用当前在字符串范围内的所有变量。因此,预期的输出将是:

Vars: 25, 123, 30

Vars: 25, 123, 30

I can achieve this by passing **dict(globals().items() + locals().items())to format(). Is this always correct or are there some corner cases that this expression would handle incorrectly?

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

Rewritten to clarify the question.

重写以澄清问题。

采纳答案by Alex Martelli

Best way to merge two dicts as you're doing (with locals overriding globals) is dict(globals(), **locals()).

合并两个字典的最佳方法(本地人覆盖全局)是dict(globals(), **locals()).

What the approach of merging globals and locals is missing is (a) builtins (I imagine that's deliberate, i.e. you don't think of builtins as "variables"... but, they COULD be, if you so choose!-), and (b) if you're in a nestedfunction, any variables that are local to enclosing functions (no really good way to get a dict with all of those, plus -- only those explicitly accessed in the nested function, i.e. "free variables" thereof, survive as cells in a closure, anyway).

缺少合并全局变量和局部变量的方法是 (a) 内置函数(我想这是故意的,即您不认为内置函数是“变量”……但是,如果您愿意,它们可能是!-),和 (b) 如果您在嵌套函数中,任何对封闭函数来说是局部的变量(并不是获得包含所有这些的 dict 的真正好方法,另外 - 只有那些在嵌套函数中显式访问的变量,即“自由变量”,无论如何都可以作为闭包中的细胞存活)。

I imagine these issues are no big deal for your intended use, but you did mention "corner cases";-). If you need to cover them, there are ways to get the built-ins (that's easy) and (not so easy) all the cells (variables from enclosing functions that you explicitly mention in the nested function -- thefunction.func_code.co_freevarsto get the names, thefunction.func_closureto get the cells, cell_contentson each cell to get its value). (But, remember, those will only be variables from enclosing functions that are explicitly accessedin your nested function's code!).

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

回答by Mark Rushakoff

Does this do what you intended?

这是否符合您的意图?

d = dict(globals())
d.update(locals())

If I read the documentation correctly, you create a copy of the globals()dict, then you overwrite any duplicates andinsert new entries from the locals()dict (since the locals()should have preference within your scope, anyway).

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



I haven't had anyluck in getting a proper function to return the full dictionary of variables in scope of the callingfunction. Here's the code (I only used pprint to format the output nicely for SO):

我没有任何运气获得适当的函数来返回调用函数范围内的完整变量字典。这是代码(我只使用 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)

and the output:

和输出:

 {'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}

Note that in the second output, we have overwritten fake_temp_var, and x is present; the first output only included the local vars within the scope of allvars_bad.

请注意,在第二个输出中,我们覆盖了fake_temp_var,并且存在 x;第一个输出仅包括allvars_bad.

So if you want to access the full variable scope, you cannot put locals() inside another function.

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



I had suspected there was some sort of frame object, I just didn't (know where to) look for it.

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

This works to your spec, I believe:

这适用于您的规格,我相信:

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()

-->

-->

{'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)>}

回答by Ned Batchelder

You could make your own:

你可以自己制作:

allvars = dict()
allvars.update(globals())
allvars.update(locals())

or combine the first two lines:

或结合前两行:

allvars = dict(globals())
allvars.update(locals())

回答by Evan Fosmark

globalVar = 25

def myfunc(paramVar):
    localVar = 30
    all_vars = locals.copy()
    all_vars.update(globals())
    print "Vars: {globalVar}, {paramVar}, {localVar}!".format(all_vars)

myfunc(123)

回答by S.Lott

Interpolation into strings works in the simplest possible way. Just list your variables. Python checks locals and globals for you.

插入字符串以最简单的方式工作。只需列出您的变量。Python 会为您检查本地变量和全局变量。

globalVar = 25

def myfunc(paramVar):
    localVar = 30
    print "Vars: %d, %d, %d!" % ( globalVar, paramVar, localVar )

myfunc(123)

回答by Nic Scozzaro

Python 3.5 or greater:

Python 3.5 或更高版本:

globalVar = 25

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

myfunc(123)