Невозможно ссылаться на одну конкретную переменную, объявленную вне функции

Я пытаюсь оживить траекторию движения снаряда с помощью Python. Для этого я использую модуль анимации matplotlib. Ниже приведен мой полный сценарий.

#!/usr/bin/env python import math import sys import matplotlib.animation as anim from matplotlib.pyplot import figure, show # Gravitational acceleration in m/s/s g = -9.81 # Starting velocity in m/s. vel = 100 # Starting angle in radians. ang = 45 * math.pi / 180 # Starting height in m. y0 = 0 # Time settings. t = 0 dt = 0.1 time = -vel**2 * math.sin(2 * ang) / g def projectile(): print g, vel, ang, y0, dt, time print t # Crashes here with UnboundLocalError: local variable 't' referenced before assignment t=0 # With this it works x = 0 y = 0.1 xc = [] yc = [] # Simulate the projectile. while t < time: x = vel * math.cos(ang) * t y = vel * math.sin(ang) * t + (g * t**2) / 2 + y0 if y < 0: break t += dt xc.append(x) yc.append(y) yield x, y def update_frame(sim): x, y = sim[0], sim[1] line.set_data(x, y) return line, def init(): line.set_data([], []) return line, # Show the results. fig = figure() ax = fig.add_subplot(111) ax.set_xlim([-5,1500]) ax.set_ylim([0,300]) # ax.plot returns a single-element tuple, hence the comma after line. line, = ax.plot([], [], 'ro', ms=5) ani = anim.FuncAnimation(fig=fig, func=update_frame, frames=projectile, blit=True, interval=20, init_func=init, repeat=False) show() 

Проблема в том, что я, кажется, могу использовать каждую переменную, кроме t . Я сделал это, чтобы создать условие остановки, чтобы он запускался только один раз, и позже я узнал о repeat=False , но мне все еще интересно. Почему я не могу использовать t внутри projectile ? Я запускаю Python 2.7.6 с Matplotlib 1.3.1 из пакета Anaconda 1.9.1.

Проблема возникает из-за попытки переназначить глобальную переменную t .

Переменные g, vel, ang, y0, dt, time вы только обращаетесь (не переназначая их), поэтому python пытается получить к ним доступ как локально, так и глобально. Однако, когда вы переназначаете t строкой t += dt , вы действительно говорите python, чтобы создать локальную переменную с идентификатором t и присвоить ей желаемое значение. Поэтому глобальный идентификатор t не может быть доступен, поскольку вы сказали python, что t является локальным, и когда вы пытаетесь получить доступ к t до его назначения, вы UnboundLocalError .

Чтобы python переназначить t как глобальную переменную, вам просто нужно добавить global t в начало вашей функции:

 t = 0 (..) def projectile(): print g, vel, ang, y0, dt, time global t # now t can be edited as a global variable print t #works x = 0 y = 0.1 xc = [] yc = [] while t < time: (..) t += dt 

РЕДАКТИРОВАТЬ:

Как указывал Flebool , вы все равно можете изменить глобальную переменную, пока вы не переназначаете идентификатор для нее. Например, приведенный ниже код:

 >>> l = [1,2,3] >>> def changelist(): ... l.append(4) ... >>> changelist() >>> l [1,2,3,4]