2013-08-16 37 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

相关问题