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 回答