UnboundLocalError: локальная переменная 'L', на которую ссылаются перед назначением Python

при попытке скомпилировать код ниже, я получаю эту ошибку

UnboundLocalError: local variable 'L' referenced before assignment 

Может кто-нибудь объяснить, почему? Разве глобальная переменная не назначена раньше всего?

Моя версия Python – 2.7.3

 #!/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() 

3 Solutions collect form web for “UnboundLocalError: локальная переменная 'L', на которую ссылаются перед назначением Python”

Минимальный код для воспроизведения вашей ошибки

 x = 1 def foo(): x += 1 foo() 

Это происходит по ряду причин

  1. Во-первых – потому что в python у нас есть изменяемые и неизменные классы. Инты неизменяемы, то есть когда вы пишете x+=1 вы фактически создаете другой объект (что неверно для определенных ints из-за оптимизаций, которые делает CPython). Фактически это x = x + 1.
  2. Второй – потому что компилятор python проверяет каждое присваивание, сделанное внутри области видимости, и делает каждую переменную, назначаемую внутри этой области локальной.
  3. Итак, как вы видите, когда вы пытаетесь увеличивать x компилятор должен получить доступ к переменной, которая является локальной для этой области, но никогда не была назначена значение раньше.

Если вы используете python2 – у вас есть возможность объявить переменную global . Но таким образом вы не сможете получить переменную от промежуточной функции, например

 x = 0 def foo(): x = 1 def bar(): global x print x # prints 0 bar() foo() 

В python3 у вас есть nonlocal ключевое слово для решения этой ситуации.

Также я бы посоветовал вам избегать использования глобальных переменных. Также есть класс collection.Counter который может быть вам полезен.

Дальнейшее чтение: документы python

Разве глобальная переменная не назначена раньше всего?

Да, но это совершенно неуместно. Компилятор видит назначение внутри функции и помечает имя как находящееся в локальной области. Вам нужно использовать ключевое слово global в начале функции, чтобы сообщить компилятору, что вместо этого имя должно быть в глобальной области.

 def compute_dv(p1,p2): global L ... 

Вы смешиваете вкладки и пробелы; не делайте этого.

Запустите свой скрипт с помощью python -tt yourscript.py и исправьте все найденные ошибки.

Затем сконфигурируйте ваш редактор, чтобы придерживаться только пробелов для отступов; использование 4 пробелов в отступе является рекомендуемым стилем в руководстве по стилю Python .

Затем вы пытаетесь увеличить глобальный L здесь:

 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, это не так.

  • Как установить ограничения на изменение размера окна в pygame
  • Не встроен ли встроенный встроенный Python DRY DRY?
  • Невозможно изменить размер изображения с помощью tkinter
  • Python 2.7: круглое число до ближайшего целого
  • В Python, почему list автоматически глобально?
  • асинхронный вызов SOAP api с использованием Python
  • Заполните и отправьте форму html
  • Скопировать файл в каталог
  • Python - лучший язык программирования в мире.