Получить изложение всех переменных, находящихся в данный момент в области видимости, и их значений
Рассмотрим этот фрагмент:
globalVar = 25
def myfunc(paramVar):
localVar = 30
print "Vars: {globalVar}, {paramVar}, {localVar}!".format(**VARS_IN_SCOPE)
myfunc(123)
куда VARS_IN_SCOPE
это дикт, который я после этого будет содержать globalVar
, paramVar
а также localVar
кроме всего прочего.
Я хотел бы в основном иметь возможность ссылаться на все переменные, которые в настоящее время находятся в области видимости внутри строки. Следовательно, ожидаемый результат будет:
Vars: 25, 123, 30
Я могу достичь этого, пройдя **dict(globals().items() + locals().items())
в format()
, Всегда ли это правильно или есть какие-то угловые случаи, которые это выражение будет обрабатывать неправильно?
Переписать, чтобы уточнить вопрос.
5 ответов
Лучший способ объединить два голоса, как вы делаете (с переопределением глобалов) dict(globals(), **locals())
,
Чего не хватает в подходе слияния глобальных и локальных объектов, так это (а) встроенных функций (я полагаю, это преднамеренно, т. Е. Вы не думаете о встроенных функциях как "переменных"... но они МОГУТ быть, если вы так решите!-), и (b) если вы находитесь во вложенной функции, любые переменные, которые являются локальными для включающих функций (не очень хороший способ получить контроль со всеми из них, плюс - только те, к которым явно обращаются во вложенной функции, т.е. их переменные, в любом случае выживают как клетки в замыкании).
Я думаю, что эти проблемы не имеют большого значения для вашего предполагаемого использования, но вы упомянули "угловые случаи";-). Если вам нужно охватить их, есть способы получить встроенные (это легко) и (не так просто) все ячейки (переменные из вложенных функций, которые вы явно упоминаете во вложенной функции - thefunction.func_code.co_freevars
чтобы получить имена, thefunction.func_closure
чтобы получить клетки, cell_contents
на каждую ячейку, чтобы получить ее значение). (Но помните, что это будут только переменные из включающих функций, к которым явно обращаются в коде вашей вложенной функции!).
Это делает то, что вы хотели?
d = dict(globals())
d.update(locals())
Если я правильно прочитал документацию, вы создаете копию globals()
dict, затем вы перезаписываете любые дубликаты и вставляете новые записи из 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)
и вывод:
{'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}
Обратите внимание, что во втором выводе мы перезаписали fake_temp_var
и х присутствует; первый вывод включал только локальные переменные в объеме 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()
->
{'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)>}
Вы можете сделать свой собственный:
allvars = dict()
allvars.update(globals())
allvars.update(locals())
или объедините первые две строки:
allvars = dict(globals())
allvars.update(locals())
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)
Интерполяция в строки работает самым простым способом. Просто перечислите свои переменные. Python проверяет локальных и глобальных для вас.
globalVar = 25
def myfunc(paramVar):
localVar = 30
print "Vars: %d, %d, %d!" % ( globalVar, paramVar, localVar )
myfunc(123)
Python 3.5 или выше:
globalVar = 25
def myfunc(paramVar):
localVar = 30
print("Vars: {globalVar}, {paramVar}, {localVar}!".format(**{**locals(), **globals()}))
myfunc(123)