web-dev-qa-db-ja.com

Python:vars()を使用して文字列を変数に割り当てる

実行時に新しい変数を作成し、後で処理するために結果のディクショナリを作成できる、つまりファイルに書き込むことができると非常に便利です。

_myDict = {}
for i in range (1,10):
    temp = "variable"+str(i) 
    vars()[temp] = myFunctionThatReturnsData() # variable1= data1, variable2 = data2,etc.
    myDict[temp] = vars(temp)
_

これは、myDict [result1]で呼び出すことができる辞書エントリ[result1:data1]を作成します。私は自分が何をしているのか本当に理解せずにvars()を使用しています。私はそれを受け取りますvars()はローカル変数(?)を含む辞書を返します、そして

vars()[x] = y

[x:y]の新しい辞書エントリを作成しますか?

{input1:data1、input2:data2}で作成されたディクショナリを渡すスクリプトがあります。このメソッドを使用して、すべての値を反復処理し、すべての結果を保存して、ファイルに出力します。このコードは、クラス内の関数内にあり、機能しています。

私の混乱の原因は、locals()をいじる方法、およびvars()がlocals()またはglobals()とどのように同等(?)であるかについてのさまざまな投稿を読んだことです。

だから私の質問は(少なくとも)2つあります:

1. vars()、または特にvars()[x] = yが正確に行うこと

2.この辞書の範囲は何ですか(私がより大きなプログラムを書くときに覚えておく必要があること)

3.これがプログラミングの良い習慣かどうか。

前もって感謝します!

25
PPTim

変数のシーケンスを作成するPythonの方法

変数のシーケンスが必要な場合は、シーケンスを作成します。次のような独立変数を作成する代わりに:

_variable0
variable1
variable2
variable3
_

listの作成を確認する必要があります。これはS.Lottが提案しているものに似ていますが(S.Lottは通常良いアドバイスを持っています)、forループにより適切にマップされます。

_sequence = []
for _ in xrange(10):
    sequence.append(function_that_returns_data())
_

(ループ変数(___)を破棄することに注意してください。ここでは、10回のパスを取得しようとしています。)

その後、データは次のように利用できます。

_sequence[0]
sequence[1]
sequence[2]
sequence[3]
[...]
sequence[9]
_

追加のボーナスとして、次のことができます。

_for datum in sequence:
    process_data(datum)
_

最初は、シーケンスを0から開始するように切り替えることができます。実際のデータを1から開始するためにさまざまなゆがみを経験することができますが、それは価値があるよりも苦痛です。ゼロベースのリストに慣れることをお勧めします。すべてがそれらの周りに構築されており、かなり自然に感じ始めます。

vars()およびlocals()

今、あなたの質問の別の部分に答えます。 vars()(またはlocals())は、Pythonによって作成された変数への低レベルのアクセスを提供します。したがって、次の2行は同等です。

_locals()['x'] = 4
x = 4
_

vars()['x']のスコープは、xのスコープとまったく同じです。 locals()(またはvars())の問題の1つは、名前空間から通常の方法では取得できないものを名前空間に配置できることです。したがって、次のようなことを行うことができます:locals()[4] = 'An integer'、ただし、ローカルを再度使用しないと、ローカルネームスペース(pythonネームスペースと同様)文字列を保持するためだけのものです。

_>>> x = 5
>>> dir()
['__builtins__', '__doc__', '__name__', 'x']
>>> locals()[4] = 'An integer'
>>> dir()
[4, '__builtins__', '__doc__', '__name__', 'x']
>>> x
5
>>> 4
4
>>> locals()[4]
'An integer'
_

4はlocals()[4]と同じものを返さないことに注意してください。これにより、予期しない、デバッグが難しい問題が発生する可能性があります。これがlocals()の使用を避ける1つの理由です。もう1つは、pythonが単純でエラーが発生しにくい方法(変数のシーケンスの作成など)を提供すること)を行うだけの場合、一般に多くの面倒なことです。

35
jcdyer

代わりにこれを行ってください。それはもっと簡単です。

_myDict = {}
for i in range (1,10):
    temp = "variable"+str(i) 
    myDict[temp] = myFunctionThatReturnsData() # variable1= data1, variable2 = data2,etc.
_

それだけで十分です。

結果は_myDict['variable1']_から_myDict['variable9']_になります

vars()またはlocals()が必要になることはほとんどありません。それらの使用をやめて、通常の変数と通常の辞書を使用してください。理解できないことは避け、単純で明白なものに固執するようにしてください。

9
S.Lott

変数のヘルプから、

vars(...)vars([object])->辞書

Without arguments, equivalent to locals().
With an argument, equivalent to object.__dict__.

Varsなしで使用しているので、locals()のヘルプを見てみましょう

locals(...)locals()->辞書

Update and return a dictionary containing the current scope's local

変数。

これで最初の2つの質問に答えられます。 vars()は、文字列として変数の名前でインデックスが付けられたローカル変数に辞書を返します。スコープはローカルです。

3番目の質問についてはわかりませんが、良い兆候ではないハックのようなもののようです。これを適切なスコープでのみ使用することについて注意を払っていれば、それでうまくいくと思います。

6
Justin Peel

jcdyerは概念を非常によく説明しており、Justin Peelがvars()locals()の機能を明確に述べています。しかし、小さな例は常に理解を速めます。

class Bull(object):

    def __init__(self):
        self.x = 1
        self.y = "this"

    def __repr__(self):
        return "Bull()"

    def test1(self):
        z = 5
        return vars()

    def test2(self):
        y = "that"
        return vars(self)

    def test3(self):
        return locals()

    def test4(self):
        y = 1
        return locals()

if __name__ == "__main__":
    b = Bull()
    print b.test1()
    print b.test2()
    print b.test3()
    print b.test4()
    print vars(b).get("y")

その結果:

{'self': Bull(), 'z': 5}
{'y': 'this', 'x': 1}
{'self': Bull()}
{'y': 1, 'self': Bull()}
this
5

私は3番目に答えることができます。これは良いプログラミング方法ではありません。あなたが達成しようとしていることは正確にはわかりませんが、locals()を使用せずにそれを行うよりエレガントな方法があると確信しています(これはvars()と同じです) help(vars)インタラクティブPythonシェル)。

3

この方法でvars/localsまたはglobalsを使用することは、(a)習慣が不十分であり、(b)すべての場合に機能するとは限りません。詳細は 動的にローカル変数を設定 を参照してください。結論:dictsを使用するだけです-それが目的です。

2
Chris Johnson