Get the dictation of all the variables currently in the region and their values

Consider this snippet:

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

Where VARS_IN_SCOPE is a dict that will then contain globalVar , paramVar and localVar , among other things.

I would like to basically refer to all the variables that are currently in the area inside the string. Therefore, the expected result will be:

Vars: 25, 123, 30

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

Rewritten to clarify the issue.

+29
python
Jun 25 '09 at 0:37
source share
5 answers

The best way to combine the two dicts as you do (with local overriding global variables) is dict(globals(), **locals()) .

What is missing in the merging of globals and local residents is (a) built-in (I assume that intentionally, that is, you donโ€™t think of built-in variables as โ€œvariablesโ€ ... but, they MAY be if you do choose! -) and (b) if you are in a nested function, any variables that are local to include functions (there is really no good way to get a dict with all of these, plus only those that are explicitly available in the nested function, i.e. . "free variables", survive as cells in closure, one way or another).

I believe these problems are not very significant for your intended use, but you mentioned "corner cases" ;-). If you need to cover them, there are ways to get the built-in (which is easy) and (not so simple) all the cells (variables from the built-in functions that you explicitly specify in the nested function - thefunction.func_code.co_freevars to get the names, thefunction.func_closure , to get cells, cell_contents in each cell to get its value). (But, remember, these will only be variables from closing functions that are explicitly available in your nested function code!).

+32
Jun 25 '09 at 2:28
source share

Does this do what you intended?

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

If I read the documentation correctly, you make a copy of globals() dict, then you overwrite any duplicates and insert new entries from locals() dict (since locals() should have preference in your area, anyway).




I was not lucky to get the correct function to return the full dictionary of variables to the scope of the calling function. Here's the code (I used only pprint for good output for 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 conclusion:

  {'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 fake_temp_var , and x is present; the first exit included only local vars within allvars_bad .

So, if you want to access the full range of variables, you cannot put locals () in another function.




I suspected that there was some kind of frame object, I just did not know (I know where) to look for it.

This works with your specification, 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)>} 
+7
Jun 25 '09 at 0:45
source share

You can make your own:

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

or combine the first two lines:

 allvars = dict(globals()) allvars.update(locals()) 
+2
Jun 25 '09 at 0:46
source share
 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) 
+2
Jun 25 '09 at 2:55
source share

Interpolation into strings works in the simplest way. Just list the variables. Python checks local and global variables for you.

 globalVar = 25 def myfunc(paramVar): localVar = 30 print "Vars: %d, %d, %d!" % ( globalVar, paramVar, localVar ) myfunc(123) 
+1
Jun 25 '09 at 2:17
source share



All Articles