UnboundLocalError:在赋值python之前引用了局部变量”l”

UnboundLocalError: local variable 'L' referenced before assignment Python

本问题已经有最佳答案,请猛点这里访问。

当试图编译下面的代码时,我得到了这个错误

1
UnboundLocalError: local variable 'L' referenced before assignment

有人能解释为什么吗?全局变量是否比其他变量先赋值?

我的python版本是2.7.3

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#!/usr/bin/env python

import pygame
from pygame.locals import *
from sys import exit
import random
import math

R = int(8)  # promien planety
N = 5  # liczba planet
G = 2  # stala"grawitacyjna"
L = 1

def compute_dv(p1,p2):
    dx = p2[0]-p1[0]
    dy = p2[1]-p1[1]
    r = math.hypot(dx,dy)
    dx /= r*r
    dy /= r*r
    if(L>1000):
   print"r=", r,"dx=", dx,"dy=", dy,"dx/ r*r =", dx,"dy/ r*r =", dy
    L+=1
    return G*dx,G*dy


def rand_color():
    r = 32*random.randint(0,7)
    g = 32*random.randint(0,7)
    b = 22*random.randint(0,7)
    return (r,g,b)


pygame.init()
screen = pygame.display.set_mode((640, 480), 0, 32)

points = []
vs = []
colors = []

for i in range(N):
    points.append( [random.randint(0,639), random.randint(0,480)] )
    vs.append( [0,0] )
    colors.append( rand_color() )

clock = pygame.time.Clock()

screen.fill( (255,255,255))

while True:
    clock.tick(30)

for event in pygame.event.get():
    if event.type == QUIT:
        exit()

for i in range(len(points)):
   for j in range(len(points)):
      if points[i]!=points[j]:
         dvx,dvy = compute_dv( points[i],points[j])
         vs[i][0] += dvx
         vs[i][1] += dvy

for i in range(len(points)):
    points[i][0] += vs[i][0]
    points[i][1] += vs[i][1]

screen.fill( (255,255,255))

for i in range(len(points)):
  L = []
  for w in points[i]:
print int(round(w))
L.append(int(round(w)))
  points[i] = L
  print points[i],"stop"
  #x = raw_input()

  pygame.draw.circle(screen, colors[i], points[i], R)  

pygame.display.update()


重现错误的最小代码是

1
2
3
4
x = 1
def foo():
    x += 1
foo()

发生这种情况的原因有很多

  • 首先,因为在Python中,我们有可变的和不可变的类。ints是不可变的,也就是说,当您编写x+=1时,实际上创建了另一个对象(由于cpython的优化,某些ints不是这样)。实际发生的是x=x+1。
  • 第二,因为python编译器检查作用域内的每个赋值,并使该作用域内的每个变量都成为局部变量。
  • 因此,正如您在尝试递增x时看到的,编译器必须访问该作用域的局部变量,但以前从未赋值。
  • 如果您使用python2,那么您只能选择声明变量global。但是这样你就不能从一个中间函数中得到一个变量

    1
    2
    3
    4
    5
    6
    7
    8
    x = 0
    def foo():
      x = 1
      def bar():
        global x
        print x  # prints 0
      bar()
    foo()

    在python3中,您有nonlocal关键字来解决这种情况。

    另外,我建议您避免使用Globals。还有一个collection.Counter类可能对您有用。

    进一步阅读:python文档


    Isn't a global variable assigned before anything else?

    是的,但这完全无关紧要。编译器在函数中看到赋值,并将名称标记为在本地作用域中。您需要在函数开头使用global关键字来告诉编译器名称应该在全局范围内。

    1
    2
    3
    def compute_dv(p1,p2):
        global L
         ...


    你在混合标签和空格,不要这样做。

    使用python -tt yourscript.py运行脚本并修复所有发现的错误。

    然后将编辑器配置为只保留缩进空间;根据《Python样式指南》,每个缩进使用4个空格是推荐的样式。

    接下来,您将尝试在这里增加全局L

    1
    2
    3
    4
    5
    6
    def compute_dv(p1,p2):
        # ...

        if(L>1000):
            print"r=", r,"dx=", dx,"dy=", dy,"dx/ r*r =", dx,"dy/ r*r =", dy
            L+=1

    而不是宣布它是全球性的。在该函数中添加global L。对函数内部名称的赋值将此类名称标记为本地名称,除非您特别告诉python它不是本地名称。