2016-04-17 6 views
1

В Python 2 (не уверен около 3) словарь locals только обновляется, когда вы на самом деле вызываете locals(). Так, например,Как я могу принудительно обновить словарь locals() Python из другого фрейма стека?

l=locals() 
x=2 
l['x'] 

терпит неудачу, потому что l не имеет ключа «х» в нем, но

l=locals() 
x=2 
locals() 
l['x'] 

возвращается 2.

Я ищу способ принудительного обновления из locals, но трюк в том, что я в другом стеке кадров. Так, например, Я ищу сделать

l=locals() 
x=2 
force_update() 
l['x'] 

и мне нужно написать функцию force_update(). Я знаю, что из указанной функции я могу получить родительский кадр через inspect.currentframe().f_back и даже родительские (не обновленные) локальные сети через inspect.currentframe().f_back.f_locals, но как я могу заставить обновление?

Если это кажется запутанным, моя главная цель - написать функцию, которая является сокращением для "{some} string".format(**dict(globals(),**locals())), поэтому мне не нужно вводить ее каждый раз, и вместо этого можно сделать fmt("{some} string"). Таким образом, я столкнулся с проблемой выше.

Редактировать: С ответом Martjin ниже, ниже по существу решение, которое я искал. Можно было бы поиграть с тем, как они получают рамку стека вызываемого абонента, здесь я делаю это через partial.

from functools import partial 
from inspect import currentframe 

fmt = partial(lambda s,f: s.format(**dict(globals(),**f.f_locals)),f=currentframe()) 
x=2 
print fmt("{x}") #prints "2" 
+0

В редакторе вы можете определить ярлык, фрагмент или любой другой текст, который редактор вызывает, чтобы он расширился до '.format (** dict (globals(), ** locals())). Многие редакторы поддерживают что-то подобное. –

+0

Почему вы используете '' {some} строку ".format (** dict (globals(), ** locals()))' столько раз в вашем коде? Вам нужна действительно ли ваша строка формата для каждой переменной в локальном и глобальном пространствах имен? – emeraldemon

+0

Если вы можете получить родительский фрейм (см. Также 'sys._getframe (1)'), то зачем вам нужны 'globals()' и 'locals()'? – cdarke

ответ

1

Просто доступа f_locals на объекте кадра запускает копию, поэтому использование inspect.currentframe().f_back.f_localsдостаточно.

Смотрите frame_getlocals() function в frameobject.c реализации:

static PyObject * 
frame_getlocals(PyFrameObject *f, void *closure) 
{ 
    PyFrame_FastToLocals(f); 
    Py_INCREF(f->f_locals); 
    return f->f_locals; 
} 

PyFrame_FastToLocals функция используется для копирования данных из массива INTERAL отслеживания значений LOCALS к словарю. frame_getlocals используется для реализации дескриптора frame.f_locals (свойство); см. frame_getsetlist definition.

PyFrame_FastToLocalsWithError функция, используемая выше именно то, чтоlocals() использует для получения того же словаря (по wrappingPyEval_GetLocals function).

+0

Aha! Благодарю. Мне удалось найти 'currentframe(). F_locals', но не понимаю, что он точно заставляет обновлять, которое я искал. – marius

+0

Да - jus остерегайтесь того, что противоположного не происходит - нет возможности обновлять быстрые переменные, изменяя значения в локалях. – jsbueno

+0

делает это для python 3 или выше? –

 Смежные вопросы

  • Нет связанных вопросов^_^