1. ホーム
  2. python

Python 2で、親スコープにある変数に書き込むにはどうしたらいいですか?

2023-08-23 05:06:10

質問

関数内に以下のようなコードがあります。

stored_blocks = {}
def replace_blocks(m):
    block = m.group(0)
    block_hash = sha1(block)
    stored_blocks[block_hash] = block
    return '{{{%s}}}' % block_hash

num_converted = 0
def convert_variables(m):
    name = m.group(1)
    num_converted += 1
    return '<%%= %s %%>' % name

fixed = MATCH_DECLARE_NEW.sub('', template)
fixed = MATCH_PYTHON_BLOCK.sub(replace_blocks, fixed)
fixed = MATCH_FORMAT.sub(convert_variables, fixed)

に要素を追加する。 stored_blocks は問題なく動作しますが num_converted を増やすことができません。

UnboundLocalError: ローカル変数 'num_converted' は代入前に参照されました。

私は global を使うこともできますが、グローバル変数は醜いですし、その変数がグローバルである必要は全くないのです。

そこで、親関数のスコープにある変数に書き込むにはどうしたらいいのか、興味があります。 nonlocal num_converted はおそらくその仕事をするでしょうが、私はPython 2.xで動作するソリューションが必要です。

どのように解決するのですか?

問題です。 これは、Pythonのスコープルールが頭悪いからです。の存在は += 代入演算子があると、ターゲットをマークします。 num_converted を包含する関数のスコープにローカルなものとしてマークし、 Python 2.xではそこから1つだけスコープレベルにアクセスする健全な方法はありません。唯一 global キーワードだけが現在のスコープから変数参照を持ち出すことができ、それはあなたを一番上まで連れて行きます。

修正しました。 ターン num_converted を単一要素の配列にする。

num_converted = [0]
def convert_variables(m):
    name = m.group(1)
    num_converted[0] += 1
    return '<%%= %s %%>' % name