2013-08-16 33 views
1

我偶然發現了一種可以關閉我對Pythons變量作用域的理解的情況。另一個UnboundLocalError:賦值之前引用的局部變量問題

下面是代碼:

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不喜歡我在第一種情況下打印價值。

回答

3

如果您爲其分配了,則Python編譯器將該名稱標記爲函數的本地名稱。您的最後一行分配給transaction_id,因此它被視爲本地名稱,而不是全局名稱。

你需要告訴編譯器明確transaction_id是一個全球性的,通過使用函數內global關鍵字:

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

如果沒有分配,一個名字被視爲非本地,而不是和你不需要標記它。

2

由於Python沒有變量聲明,它需要另一種方式來告訴什麼是本地的什麼範圍。它通過定義函數指定的任何內容對於該函數來說是本地的,除非被聲明覆蓋。因此,分配給transaction_id使其成爲本地,並且print嘗試打印未分配的本地並失敗。

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 # <---------------------- 
+0

我不使用全局變量,我只是對這個範圍現象感到困惑。我不得不做這個例子,儘可能簡潔地提出我的問題。 – bioffe

相關問題