UnboundLocalError:赋值前引用的局部变量“len”

Zaf*_*aji 4 python python-2.7

print "welcome to the average finder"
print """Insert the values you want to find the average for,
when you insert all the values type 'done'"""

values = []

def insert_values():
    action = raw_input("> ")

    if 'done' in action :
        calculating_average()
    elif action != 'done':
        x = int(action)
        values.append(x)
        insert_values()
    else:
        print "please insert values then type done"
        insert_values()

def calculating_average():

    len = len(values)
    sum = sum(values)

    final = sum / len 
    print final

insert_values()
Run Code Online (Sandbox Code Playgroud)

该脚本的目的:向用户询问数字,然后让脚本找到数字的平均值并显示它。我创建了一个名为值的空列表,将用户输入的数字转换为整数后附加它们。

我不断收到 UnboundLocalError: 在赋值之前引用局部变量 'len'...即使我认为我确实将 len 和 sum 分配给列表中元素的长度和总和。

PS我是Python新手,通常当我遇到错误时,我会尝试自己修复它或研究它,但对于这个我真的不明白为什么我会收到这个错误......任何见解将不胜感激!

pax*_*blo 7

关于您的代码:

len = len(values)
sum = sum(values)
Run Code Online (Sandbox Code Playgroud)

您可能不想对变量和函数(1)使用相同的名称:

>>> x = [1,2,3]

>>> len(x)
3

>>> len = len(x)
>>> len
3

>>> len(x)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'int' object is not callable
Run Code Online (Sandbox Code Playgroud)

就您而言,错误消息UnboundLocalError: local variable 'len' referenced before assignment很有趣,但这是由于特定的 Python 功能造成的。

除非函数内的变量被标记为global,否则在函数内的任何位置重新绑定它都会导致该函数内的任何位置(甚至重新绑定点之前)将其视为局部变量。

因此len = len(something),导致len被归类为局部变量,因此您在设置之前尝试使用它(通过将其作为函数调用)。

要解决该问题,请将您的函数更改为如下所示:

def calculating_average():
    value_len = len(values)
    value_sum = sum(values)
    final = value_sum / value_len 
    print final
Run Code Online (Sandbox Code Playgroud)

最后一点,我还发现了另外两个潜在的问题。第一个是如果您不输入数字(即立即输入),则会出现除零错误done

第二个是……不寻常的……使用递归来返回并获取下一个数字。我会认真考虑重构您的代码,以便通过循环完成此操作。


(1)在某些时候,每个 Python 开发人员都会顿悟到“名称/对象的区别”。

我的意思是,Python 中的每个对象本质上都是“未命名的”,我们以各种方式绑定到它们。当从对象中删除最后一个绑定时,该对象将变得不可访问,因此需要进行处置(垃圾收集)。例如,代码:

a = [1, 2, 3]
b = a
Run Code Online (Sandbox Code Playgroud)

创建两个名称,但只创建一个对象,这意味着a[1] = 42将影响 和ab名称”,因为同一个对象被两者绑定:

  a   b
   \ /
    V
    [1, 42, 3]
Run Code Online (Sandbox Code Playgroud)

就是导致诸如 之类的语句出现问题的原因len = len(x)

在执行之前,该len名称会绑定到一个函数,该函数会执行您所期望的操作,计算出某个对象的长度。执行后,它绑定到该函数返回的值。

到那时,执行就something = len(something_else)与执行没有什么不同了something = 3(something_else)

还要注意,这种意义上的“绑定”是模式,而不仅仅是像name = some_object. 它还包括“匿名”绑定,例如my_list.append(42)- 列表中的每个条目都是到该位置的对象的绑定(在本例中,my_list[-1]绑定到 object 42)。