我正面临着从类波波纹中实现方法动画的问题 . animation 方法旨在创建波传播的动画 . 我不希望 animation 方法修改 Wave 对象的状态实例变量u,因此我试图在方法 animation 中创建局部变量u . 不过,我不知道如何将 animation 方法中的局部变量u传递给 animation 方法中定义的 animate 函数 . 在我试图实现的方式中,从我的概念来看,方法 animation 的局部变量 u 应该是 animate 方法的全局变量之王(在 animation 方法中定义) . 但是,这个假设是明确的错误,否则我不会得到错误 . 作为补充信息,我得到的错误是: UnboundLocalError: local variable 'u' referenced before assignment . 如果有人向我指出我想要的实施方式,我将很高兴 .
提前致谢
class Wave(object):
def __init__(self, phenomenon):
'''
nx: Number of spatial grid points
dx: Distance between any pair of adjacent grid points
nt: Number of steps in time
nu: Diffusion coefficient
dt: Value of the step in time
c: wave velocity
u: grid vector of the wave
'''
if phenomenon == 'convection':
self.phenomenon = phenomenon
self.nx = 81
self.dx = 2.0/(self.nx - 1) # Distance between any pair of adjacent grid
self.nt = 100
self.dt = 0.002
self.c = 3
self.x = numpy.linspace(0,4,self.nx)
self.u = numpy.ones(self.nx)
self.lbound = numpy.where(self.x >= 0.5)
self.ubound = numpy.where(self.x <= 1.0)
self.bounds = numpy.intersect1d(self.lbound[0], self.ubound[0])
self.u[self.bounds] = 2
if phenomenon == 'diffusion':
...
if phenomenon == 'burgers':
...
def _convection(self, u):
un = u.copy()
u[1:] = un[1:] - self.c*self.dt/self.dx*(un[1:] - un[:-1])
u[0] = 1.0
return u
def integration(self):
if self.phenomenon == 'convection':
for n in range(1,self.nt):
self.u = self._convection(u=self.u)
if self.phenomenon == 'diffusion':
...
if self.phenomenon == 'burgers':
...
def animation(self):
fig = plt.figure()
ax = plt.axes(xlim=(0,4), ylim=(0,3))
ax.grid()
line, = ax.plot([], [], 'o-', lw=2)
time_template = 'time = %.2fs'
time_text = ax.text(0.05, 0.9, '', transform=ax.transAxes)
def init():
line.set_data([], [])
time_text.set_text('')
return line, time_text
x = self.x
u = self.u.copy()
def animate(i):
if self.phenomenon == 'convection':
u = self._convection(u=u)
if self.phenomenon == 'diffusion':
...
if self.phenomenon == 'burgers':
...
line.set_data(x,u)
time_text.set_text(time_template % (i*self.dt))
return line, time_text
anim = animation.FuncAnimation(fig, animate, frames=500, init_func=init, interval=10, blit=True)
plt.show()
EDIT
完成跟踪错误:
Tkinter回调中的异常回溯(最近一次调用最后一次):文件“/usr/lib/python2.7/lib-tk/Tkinter.py”,第1489行,在调用中返回self.func(* args)文件“/ usr /lib/python2.7/lib-tk/Tkinter.py“,第536行,在callit func(* args)文件中”/usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py“,第141行,在_on_timer中TimerBase._on_timer(self)文件“/usr/lib/pymodules/python2.7/matplotlib/backend_bases.py”,第1203行,在_on_timer中ret = func(* args,** kwargs)文件“/ usr / lib / pymodules / python2.7 / matplotlib / animation.py“,第876行,在_step中still_going = Animation._step(self,* args)文件”/usr/lib/pymodules/python2.7/matplotlib/animation.py“ ,第735行,在_step self._draw_next_frame(framedata,self._blit)文件“/usr/lib/pymodules/python2.7/matplotlib/animation.py”,第754行,在_draw_next_frame self._draw_frame(framedata)文件中“/ usr / lib / pymodules / python2.7 / matplotlib / animation.py“,第1049行,_draw_frame self._drawn_artists = self._func(framedata,* self._args)文件”wave.py“,l ine 201,in animate un = u.copy()UnboundLocalError:赋值前的局部变量'u'在Tkinter回调中的异常回调Traceback(最近一次调用last):文件“/usr/lib/python2.7/lib-tk/Tkinter .py“,第1489行,在调用return self.func(* args)文件”/usr/lib/python2.7/lib-tk/Tkinter.py“,第536行,在callit func(* args)文件中”/ usr / lib / pymodules / python2.7 / matplotlib / backends / backend_tkagg.py“,第141行,在_on_timer中TimerBase._on_timer(self)文件”/usr/lib/pymodules/python2.7/matplotlib/backend_bases.py“,第1203行,在_on_timer中ret = func(* args,** kwargs)文件“/usr/lib/pymodules/python2.7/matplotlib/animation.py”,第876行,在_step中still_going = Animation._step(self,* args)文件“/usr/lib/pymodules/python2.7/matplotlib/animation.py”,第735行,在_step self._draw_next_frame(framedata,self._blit)文件“/usr/lib/pymodules/python2.7/ matplotlib / animation.py“,第754行,在_draw_next_frame self._draw_frame(framedata)文件”/usr/lib/pymodules/python2.7/matplotlib/animation.py“,l ine 1049,在_draw_frame中self._drawn_artists = self._func(framedata,* self._args)文件“wave.py”,第201行,在动画中un = u.copy()UnboundLocalError:在赋值之前引用的局部变量'u'
1 回答
在Python中使用闭包捕获变量时,不允许分配给它 . 如果Python看到你分配给它,那么就不允许从封闭范围中捕获它;它必须是一个新的函数局部变量(
animate
函数的本地变量) . 但是既然你正在尝试使用捕获的_2530169来初始化它,你需要u
的值,但是在这个上下文中Python决定u
必须是animate
的本地,所以它不是在看animate
's enclosing scope. That'为什么你得到那个错误 .在你的情况下解决这个问题的简单方法就是将
animate
定义为这明确地将
u
的副本传递给animate
.