另一个UnboundLocalError:在赋值问题之前引用的局部变量

时间:2013-08-16 19:08:32

标签: python python-2.7

我偶然发现了一个让我理解Pythons变量范围的情况。

以下是代码:

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 个答案:

答案 0 :(得分:4)

Python编译器将名称标记为函数的本地名称(如果已分配给它)。您的最后一行分配给transaction_id,因此它被视为本地名称,而不是全局名称。

您需要使用函数内的transaction_id关键字告诉编译器显式 global是全局的:

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

如果没有作业,则名称将被视为非本地名称,您无需对其进行标记。

答案 1 :(得分:3)

由于Python没有变量声明,因此需要另一种方法来告诉什么范围是本地的。它通过定义函数赋予的任何内容对该函数是本地的,除非被global声明覆盖。因此,分配给transaction_id使其成为本地,print尝试打印未分配的本地并失败。

答案 2 :(得分: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    # <----------------------