4

Python 2 (3 については不明) では、locals 辞書は、実際に locals() を呼び出したときにのみ更新されます。だから例えば

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

lキー「x」が含まれていないため失敗しますが、

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

2 を返します。

ローカル辞書を強制的に更新する方法を探していますが、秘訣は別のスタック フレームにいることです。だから例えば私はやろうとしている

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"
4

1 に答える 1

2

フレーム オブジェクトにアクセスするf_localsだけでコピーがトリガーされるため、 を使用inspect.currentframe().f_back.f_locals するだけで十分です。

実装のframe_getlocals()関数を参照してください。frameobject.c

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

PyFrame_FastToLocalsローカル値を追跡する内部配列からディクショナリにデータをコピーするために使用される関数です。記述子(プロパティ)frame_getlocalsを実装するために使用されます。定義frame.f_localsを参照してください。frame_getsetlist

PyFrame_FastToLocalsWithError上で使用された関数は、(関数をラップすることによって)同じ辞書を生成するために使用されるものとまったく同じです。locals()PyEval_GetLocals

于 2016-04-17T15:10:02.413 に答える