Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/python-2.7/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 无法引用在函数外部声明的特定变量_Python_Python 2.7_Matplotlib_Scope - Fatal编程技术网

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

Python 无法引用在函数外部声明的特定变量,python,python-2.7,matplotlib,scope,Python,Python 2.7,Matplotlib,Scope,我正在尝试使用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 ve

我正在尝试使用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()
#/usr/bin/env python
输入数学
导入系统
将matplotlib.animation作为动画导入
从matplotlib.pyplot导入图中,显示
#重力加速度,单位为m/s/s
g=-9.81
#起动速度(m/s)。
水平=100
#以弧度为单位的起始角度。
ang=45*math.pi/180
#起始高度(m)。
y0=0
#时间设置。
t=0
dt=0.1
时间=-vel**2*math.sin(2*ang)/g
def射弹():
打印g、vel、ang、y0、dt、时间
print t t#在此崩溃,未绑定LocalError:赋值前引用了局部变量“t”
t=0#这样就行了
x=0
y=0.1
xc=[]
yc=[]
#模拟射弹。
当t<时间:
x=标高*数学系数(ang)*t
y=vel*math.sin(ang)*t+(g*t**2)/2+y0
如果y<0:
打破
t+=dt
附加(x)
yc.追加(y)
产量x,y
def更新_帧(sim):
x、 y=sim[0],sim[1]
行。设置_数据(x,y)
回程线,
def init():
行。设置_数据([],[])
回程线,
#显示结果。
图=图()
ax=图添加_子批次(111)
ax.set\u xlim([-51500])
ax.set_ylim([0300])
#plot返回单个元素元组,因此在第行后面加逗号。
直线,=ax.绘图([],[],'ro',ms=5)
ani=anim.FuncAnimation(图=fig,func=update\u frame,frames=sparket,blit=True,interval=20,init\u func=init,repeat=False)
show()

我的问题是,我似乎能够使用每个变量,除了
t
。我这样做是为了创建一个停止条件,这样它只运行一次,后来我发现了关于
repeat=False
,但我仍然对此感到好奇。为什么我不能在
投射物内使用
t
?我正在从Anaconda 1.9.1包运行Python 2.7.6和Matplotlib 1.3.1。

出现问题的原因是您试图重新分配全局变量
t

变量
g、vel、ang、y0、dt、time
只能访问(不重新分配),因此python尝试在本地和全局访问它们。但是,当您使用
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

这是非常误导的。问题不在于更改变量
t
,而在于将标识符
t
分配给其他对象。例如,如果您使用顶部定义的
t=numpy.array([0,3])
,然后尝试在
sparket()
中更改
t[1]
,而不声明它为
global
,它仍然有效。@flebool谢谢,您说得对。我已经相应地更新了我的答案。干得好。我要说的是,链接中的引用仍然是误导性的,我会把它去掉,但这只是我的想法opinion@flebool不,我同意——引文看起来太棒了,所以我尽力保留它
>>> l = [1,2,3]
>>> def changelist():
...    l.append(4)
...
>>> changelist()
>>> l
[1,2,3,4]