1. ホーム
  2. python

[解決済み] ローカル変数の動的な設定 [重複]。

2022-11-24 23:53:37

質問

Pythonでローカル変数を動的に設定する方法(変数名が動的な場合)は?

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

すでに投稿されている他の回答とは異なり、以下のような変更はできません。 locals() を直接修正して動作することを期待することはできません。

>>> def foo():
    lcl = locals()
    lcl['xyz'] = 42
    print(xyz)


>>> foo()

Traceback (most recent call last):
  File "<pyshell#6>", line 1, in <module>
    foo()
  File "<pyshell#5>", line 4, in foo
    print(xyz)
NameError: global name 'xyz' is not defined

修正 locals() は未定義です。関数の外側で locals()globals() が同じであればうまくいきますが、関数内では 通常 は動作しません。

辞書を使うか、オブジェクトに属性を設定する。

d = {}
d['xyz'] = 42
print(d['xyz'])

を使うか、あるいは好みに応じてクラスを使ってください。

class C: pass

obj = C()
setattr(obj, 'xyz', 42)
print(obj.xyz)

編集 : 関数ではない名前空間の変数(モジュール、クラス定義、インスタンスなど)へのアクセスは、通常、辞書検索で行われます(コメントでSvenが指摘しているように、例外もあります。 __slots__ ). 関数ローカルは、コンパイラが (通常) 事前にすべての名前を知っているので、高速化のために最適化されることがあり、そのため locals() .

PythonのC言語実装では locals() (関数内から呼び出される) は、ローカル変数の現在の値から初期化された普通の辞書を作成します。各関数内で任意の数の locals() を何回呼んでも同じ辞書を返しますが、すべての locals() を呼び出すたびに、ローカル変数の現在の値で更新されます。このため、辞書の要素への代入が無視されているような印象を与えることがあります(当初はこのように書いていました)。から返された辞書内の既存のキーに対する変更は locals() から返された辞書内の既存のキーに対する変更は、次に locals() を呼び出すまでです。

IronPythonでは少し違った動きをします。を呼び出すすべての関数は locals() を呼び出す関数はそのローカル変数に辞書を使うので、ローカル変数への代入は辞書を変更し、辞書への代入は変数を変更します。 しかし を明示的に呼び出した場合のみです。 locals() をその名前で呼び出した場合のみです。もし、違う名前を locals 関数を呼び出すと、その名前がバインドされたスコープのローカル変数が返され、それを通して関数のローカルにアクセスする方法はありません。

>>> def foo():
...     abc = 123
...     lcl = zzz()
...     lcl['abc'] = 456
...     deF = 789
...     print(abc)
...     print(zzz())
...     print(lcl)
...
>>> zzz =locals
>>> foo()
123
{'__doc__': None, '__builtins__': <module '__builtin__' (built-in)>, 'zzz': <built-in function locals>, 'foo': <function foo at 0x000000000000002B>, '__name__': '__main__', 'abc': 456}
{'__doc__': None, '__builtins__': <module '__builtin__' (built-in)>, 'zzz': <built-in function locals>, 'foo': <function foo at 0x000000000000002B>, '__name__': '__main__', 'abc': 456}
>>>

これはすべていつでも変更可能です。唯一保証されていることは locals() .