首页 > 解决方案 > UnboundLocalError:赋值前引用的局部变量

问题描述

我在正在循环的函数中收到未绑定的本地错误。我在第一次迭代中没有收到错误,只有在第二次(很可能也是之后的一次)中才出现错误。

我试过了:

  1. 将 accessKey 和 secretKey 初始化为全局变量,并将“global”关键字放入函数中。
  2. 在第一次迭代后清除/删除这些变量。

似乎都不起作用

# key_file[0] is a csv-file with columns: tenant, api_key, secret_key
def keys(tenant):
    for line in key_file[0]:
        if tenant == line.get('tenant'):
            accessKey = line.get('api_key')
            secretKey = line.get('secret_key')
    return  accessKey, secretKey

# tenant_list is a list with the names of the tenant

for tenant in tenant_list:
    keypair = keys(tenant) 
    print(keypair)

标签: pythonfunction

解决方案


我怀疑您的代码有两个问题。它们结合在一起给出了您所看到的异常,但即使您可以立即缓解异常,最终仍需要修复错误。

第一个错误有点投机,但我怀疑这key_file[0]是一个迭代器(可能是 acsv.DictReader或类似的东西)。当您第一次迭代它时keys,它会按预期工作,迭代器中的项目在需要时被使用。问题是第二次keys被调用,因为那时的迭代器已经用尽了,所以迭代它根本不会做任何事情。循环立即结束。

解决此问题的方法可能是将迭代器转储到一个序列中,您可以根据需要对其进行多次迭代。这可以通过等效于key_file[0] = list(key_file[0])某处来完成(您可能只需将list调用放入任何现有代码第一次分配该值的任何现有代码中,而不是先分配迭代器,然后再将其转换为列表)。另一种方法可能是将整个文件打开和 CSV 解析逻辑移动到keys(或移动到可以调用的函数中keys),以便您可以在需要时重新创建迭代器。

另一个问题是,每当您请求keys不在您的文件中的租户时,您的函数都会引发一个奇怪的异常。现在,提出一些异常可能是正确的做法,但是UnboundLocalError您现在得到的异常远没有类似的情况那么清楚ValueError(f"Unknown tenant {tenant}")

解决第二个问题最自然的方法可能是将return调用移动到if循环内的块中,以便在找到键时立即返回它们。然后,如果您在循环结束时没有找到任何内容,则可以引发适当的异常。如果您确实需要保留搜索整个文件并返回最后一个匹配行的键的逻辑,您可以将您的fooKey值初始化为某个标记值None,然后在循环后检查它们是否已更改(提出他们没有的例外)。

无论如何,这是我的一般修复:

key_file[0] = list(csv.DictReader(...))  # this is somewhere above, probably


def keys(tenant):
    for line in key_file[0]:
        if tenant == line.get('tenant'):
            accessKey = line.get('api_key')
            secretKey = line.get('secret_key')
            return accessKey, secretKey           # return immediately if a match is found

    raise ValueError(f"Unknown tenant: {tenant}")  # it's an error if you reach here

推荐阅读