无法引用在函数外部声明的特定变量

2024-06-16 11:50:31 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试用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,但我仍然对此很好奇。为什么我不能在projectile内使用t?我运行的是python2.7.6,matplotlib1.3.1来自anaconda1.9.1包。在


Tags: inimporttimematplotliblinedtfigmath
1条回答
网友
1楼 · 发布于 2024-06-16 11:50:31

问题是因为您试图重新分配全局变量t。在

变量g, vel, ang, y0, dt, time只访问(不重新分配它们),因此python尝试在本地和全局访问它们。但是,当您使用t += dt重新分配t时,实际上是在告诉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所指出的,实际上只要不重新分配全局变量的标识符,就仍然可以更改它。例如,下面的代码是有效的:

^{pr2}$

相关问题 更多 >