3

関数がありますP()。を呼び出すと、変数load_variables()が与えられます。 キーワード引数としてデフォルトを受け入れることができるはずです。Pxload_variables

これはどのように行うことができますか?

私は以下を試しました:

import inspect
def P():
    x = 1
    load_variables(x = 2)
    return x

def load_variables(**kargs):
    stack = inspect.stack()
    try:
        locals_ = stack[1][0].f_locals
    finally:
        del stack
    for __k, __v in kargs.iteritems():
        locals_[__k] = __v

print P() # => should print 2

のスコープにブリードしたいx = 1ので、実際には線がそこにあるべきではありません。load_variables()xP

これを行う別の、おそらくより良い方法はありますか?私が欲しいのは:

  1. 変数にはデフォルト値があります。たとえばx = 2、上記の。への呼び出しload_variables()などです。
  2. load_variablesたとえば、load_varibales()変数の辞書にアクセスできる場合、これらを上書きできます。xすでにここにある場合は、上書きして、xデフォルトの引数として指定されたものの代わりにこれをスピルします。
4

3 に答える 3

1

更新:DSMが以下に示すように、更新locals()はサポートされていません。したがって、少なくともCPythonの場合、答えは正しくありません。

load_variables()辞書を返しlocals()、ローカル変数を更新するために使用できますか?

def P():
    x=1
    locals().update(load_variables(x=2))
    return x

def load_variables(**kargs):
    res={}
    for __k, __v in kargs.iteritems():
        res[__k] = __v
    return res

x=1必須であるか、そうでない場合xはバイトコードコンパイラによってグローバル変数と見なされ、次のNameError例外が発生することに注意してください。return x

あなたが本当にあなたを取り除きたいのなら、代わりにx=1私たちができますretrun locals()['x']

于 2012-08-06T09:12:17.847 に答える
1

Pythonコンパイラとバイトコードインタプリタは、可能な場合、定義されたサイズの配列へのスロットとしてローカル変数への参照を処理します。つまり、ローカル変数がスコープ内で初期化(割り当て)されていない場合、言語は変数のスロットがスコープ内に存在することを認識せず、代わりに、囲んでいるスコープまたはグローバルスコープ内の変数を探します。関数の分解を見てPください:

def P():
    load_variables(x=2)
    return x

dis.dis(P)
  2           0 LOAD_GLOBAL              0 (load_variables)
              3 LOAD_CONST               1 ('x')
              6 LOAD_CONST               2 (2)
              9 CALL_FUNCTION          256
             12 POP_TOP             

  3          13 LOAD_GLOBAL              1 (x)
             16 RETURN_VALUE        

xローカルスコープでへの割り当てがないPと、グローバルスコープでそれを探すことがわかります。

これを行う正しい方法はload_variables、解凍を使用して、関数が返すと予想される変数を明示的に示すことです。

x, y, z = load_variables(...)
于 2012-08-06T09:18:29.827 に答える
1

ここでPythonについて話しているので、おそらくそれを行う方法がありますが、私は疑問に思います:あなたは試してみるべきですか?

通常、共有ストレージ/値オブジェクトを定義してから、それを渡す方がはるかに優れています。

data = {}

def P(data):
     load_variables(data, x=2)
     return data['x']

def load_variables(data, **kargs):
     data.update(kargs)

そうすれば、予期しない副作用が発生することはありません。

于 2012-08-06T10:01:56.410 に答える