3

私は、Python の変数スコープに関する私の理解を打ち砕くような状況に出くわしました。

コードは次のとおりです。

transaction_id = None


def parseFileContent(hostID,marketID, content, writeToDB=False):
    features = _buildObjects(StringIO.StringIO(content))

    for feature in features:
        featureID =  adapter.addFeature(feature.name,boris)
        print transaction_id #breaks here UnboundLocalError: local variable 'transaction_id' referenced before assignment

        transaction_id = adapter.addFeatureTransactionToQueue(featureID, result[0], result[1], Command.ADD, boris, trans_id = transaction_id)

最後の行を

       adapter.addFeatureTransactionToQueue(featureID, result[0], result[1], Command.ADD, boris, trans_id = transaction_id)

すべてが機能します。最初のシナリオで値を出力することについて、python が何を嫌っているのかを理解する必要があります。

4

3 に答える 3

4

Python コンパイラは、名前を関数に割り当てた場合、その名前を関数に対してローカルとしてマークします。最後の行はに割り当てられるtransaction_idため、グローバルではなくローカル名として表示されます。

関数内でキーワードを使用して、グローバルであることを明示的にコンパイラに伝える必要があります。transaction_idglobal

def parseFileContent(hostID,marketID, content, writeToDB=False):
    global transaction_id

割り当てがない場合、名前は代わりに非ローカルと見なされ、マークする必要はありません。

于 2013-08-16T19:13:08.863 に答える
3

Python には変数宣言がないため、何がどのスコープに対してローカルかを伝える別の方法が必要です。globalこれは、宣言によってオーバーライドされない限り、関数が割り当てるものはすべてその関数に対してローカルであることを定義することによって行われます。したがって、に割り当てるとtransaction_idローカルになり、printは割り当てられていないローカルを印刷しようとして失敗します。

于 2013-08-16T19:13:34.970 に答える
0

関数内の名前に割り当てると、それはローカル名になります。同じ名前のグローバル変数がある場合でも、Python はその名前をその関数内でローカルとしてのみ扱います。これは、ローカルが見つからない場合、同じ名前のグローバルが存在する場合に使用される他の一部の言語とは異なります。

グローバル変数は避けるべきです。transaction_idこの場合、グローバルである必要はありません。したがって、None割り当てを関数内に配置するだけです。関数の実行後に最後のトランザクション ID にアクセスしたい場合は、単に関数からそれを返します。

def parseFileContent(hostID,marketID, content, writeToDB=False):
    features = _buildObjects(StringIO.StringIO(content))
    transaction_id = None     # <----------------------

    for feature in features:
        featureID =  adapter.addFeature(feature.name,boris)
        print transaction_id  # now works

        transaction_id = adapter.addFeatureTransactionToQueue(featureID, 
            result[0], result[1], Command.ADD, boris, trans_id=transaction_id)

     return transaction_id    # <----------------------
于 2013-08-16T19:16:40.287 に答える