既存のコードを改善しようとしていますが、辞書、リスト、またはタプルを使用せずに複数の異なる変数に影響を与える方法はありますか?? 私は次のようなものを書こうとしています:
number1 = 1
number2 = 2
number3 = 3
for i in (1,2,3):
number{i} += 1
number1 = 2 number2 = 3 および number3 = 4
文字列のフォーマットを考えていましたが、うまくいきません。
ドキュメントに記載され、コードスニペットで示されているように、辞書を変更すると、期待どおりに動作しないglobals()
場合locals()
がありますが、返された辞書を使用して、名前の文字列表現を介して変数にアクセスできます。locals()
この回答の下部にあります。また、を使用して文字列ラベルを介してインスタンス、クラス、またはモジュール変数を変更することもできます。setattr(self, 'some_variable_name', value)
ここsetattr(ClassName, 'some_variable_name', value)
でsetattr(ModuleName, 'some_variable_name', value)
、self、ClassName、およびModuleNameは、それぞれクラスインスタンス、クラス、およびモジュールへの参照です。exec
最後に、文字列に含まれるコードを実行するために使用することで、いつでも目的を達成できます。例えば:
for i in range(5):
temp = i
exec('var%d = temp' % i)
print var0, var1, var2, var3, var4
印刷します0 1 2 3 4
。
しかし、一体なぜあなたはこれらのことのいずれかをしたいのですか?任意の文字列を値にマップする必要がある場合は、代わりに辞書を作成して使用できます。あなたの例のように、任意の文字列を扱っているのではなく、名前の最後に整数のインデックスだけが異なる一連の変数を扱っている場合は、リストを使用します。これがリストの目的だからです。
最初の段落で説明した方法のいずれかで物事を行うことは、混乱を招き、無意味であり、実際のコードで行われるのを見たことがありません。
Ashwini Chaudharyがすでに指摘しているように、ここで重要なことは、文字列を値にマップする必要がある場合は、単に辞書-これらの関数はそれぞれ辞書を返すため、globals()
またはを使用すると、とにかく間接的に実行していることとまったく同じです。locals()
とにかく、追記として、locals()辞書を変更すると、物事が正しく機能しないことを述べました。これは、ドキュメントに記載されているように変更することを意図したものではありません。
Note The contents of this dictionary should not be modified; changes may not affect the values of local and free variables used by the interpreter.
さて、ここにその点の実例があります、そしてそれは誰もがこのアプローチを試みることを思いとどまらせるかもしれません:
var1 = 'asdf'
def test1():
var1 = 'ghjkl'
print globals()['var2']
print locals()['var2']
test1()
def test2():
globals()['var2'] = 'qwerty'
locals()['var2'] = 'uiop'
print var2
test2()
上記のコードを実行すると何が出力されますか?驚いたことに、それは次のとおりです。
asdf
ghjkl
qwerty
最初のテストは期待どおりに動作します。グローバルでのルックアップは関数の外部で割り当てられた値を検出し、ローカルでのルックアップはローカルで割り当てられた値を検出します。2番目のテストは驚くべきものです。グローバルに値を割り当て、ローカルに値を割り当てたとしても、変数を名前でローカルに参照すると、ローカルの値ではなく、グローバルディクショナリに配置した値が見つかります。
ここでのより良いアプローチは、ディクショナリを使用することです:
In [26]: numbers={'number1': 1,
....: 'number2' : 2,
....: 'number3' : 3}
In [27]: for i in (1,2,3):
....: numbers['number'+str(i)]+=1
....:
In [28]: numbers['number1']
Out[28]: 2
In [29]: numbers['number2']
Out[29]: 3
In [30]: numbers['number3']
Out[30]: 4
それ以外の場合は、次のこともできますglobals()
。
In [31]: number1 = 1
In [32]: number2 = 2
In [33]: number3 = 3
In [34]: for i in (1,2,3):
....: globals()['number'+str(i)]+=1
....:
....:
In [35]: number1
Out[35]: 2
In [36]: number2
Out[36]: 3
In [37]: number3
Out[37]: 4