在类中传递变量的问题 - python

时间:2016-03-28 19:07:55

标签: python class animation matplotlib

我正面临着来自波浪波浪的方法动画实施的问题。 动画方法旨在创建波传播的动画。我不希望动画方法修改 Wave 对象的状态实例变量u,因此我试图在方法中创建一个局部变量u强>动画即可。然而,我不知道如何从动画方法中为动画方法中定义的动画函数传递局部变量u。在我试图实现的方式中,从我的概念来看,方法动画的局部变量 u 应该是 animate的全局变量之王方法(在动画方法中定义)。但是,这个假设是明确的错误,否则我不会得到错误。作为补充信息,我得到的错误是: UnboundLocalError:局部变量' u'在分配前引用。 如果有人向我指出我想要的实施方式,我将很高兴。

提前致谢

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()

修改

完成跟踪错误:

  

Tkinter回调Traceback中的异常(大多数   最近的呼叫最后):文件&#34; /usr/lib/python2.7/lib-tk/Tkinter.py" ;,行   1489,在通话       return self.func(* args)File&#34; /usr/lib/python2.7/lib-tk/Tkinter.py" ;,第536行,在callit中       func(* args)File&#34; /usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py",   第141行,在_on_timer中       TimerBase._on_timer(self)File&#34; /usr/lib/pymodules/python2.7/matplotlib/backend_bases.py" ;,第1203行,   在_on_timer中       ret = func(* args,** kwargs)File&#34; /usr/lib/pymodules/python2.7/matplotlib/animation.py" ;, line 876,in   _步       still_going = Animation._step(self,* args)File&#34; /usr/lib/pymodules/python2.7/matplotlib/animation.py" ;, line 735,in   _步       self._draw_next_frame(framedata,self._blit)File&#34; /usr/lib/pymodules/python2.7/matplotlib/animation.py" ;,第754行,in   _draw_next_frame       self._draw_frame(framedata)文件&#34; /usr/lib/pymodules/python2.7/matplotlib/animation.py" ;,第1049行,   _draw_frame       self._drawn_artists = self._func(framedata,* self._args)文件&#34; wave.py&#34;,201行,在动画中       un = u.copy()UnboundLocalError:局部变量&#39; u&#39;在赋值之前引用Tkinter回调中的异常回溯(最近的   最后调用):文件&#34; /usr/lib/python2.7/lib-tk/Tkinter.py" ;,第1489行,   在通话       return self.func(* args)File&#34; /usr/lib/python2.7/lib-tk/Tkinter.py" ;,第536行,在callit中       func(* args)File&#34; /usr/lib/pymodules/python2.7/matplotlib/backends/backend_tkagg.py",   第141行,在_on_timer中       TimerBase._on_timer(self)File&#34; /usr/lib/pymodules/python2.7/matplotlib/backend_bases.py" ;,第1203行,   在_on_timer中       ret = func(* args,** kwargs)File&#34; /usr/lib/pymodules/python2.7/matplotlib/animation.py" ;, line 876,in   _步       still_going = Animation._step(self,* args)File&#34; /usr/lib/pymodules/python2.7/matplotlib/animation.py" ;, line 735,in   _步       self._draw_next_frame(framedata,self._blit)File&#34; /usr/lib/pymodules/python2.7/matplotlib/animation.py" ;,第754行,in   _draw_next_frame       self._draw_frame(framedata)文件&#34; /usr/lib/pymodules/python2.7/matplotlib/animation.py" ;,第1049行,   _draw_frame       self._drawn_artists = self._func(framedata,* self._args)文件&#34; wave.py&#34;,201行,在动画中       un = u.copy()UnboundLocalError:局部变量&#39; u&#39;在分配前引用

1 个答案:

答案 0 :(得分:2)

在Python中使用闭包捕获变量时,不允许分配给它。如果Python看到你分配给它,那么就不允许从封闭范围中捕获它;它必须是一个新的函数局部变量(animate函数的本地变量)。但是,由于您尝试使用捕获的u来初始化它,您需要u的值,但在此上下文中,Python已决定u必须是animate的本地值1}},所以它不是在看animate的封闭范围。这就是你得到这个错误的原因。

在您的情况下解决这个问题的简单方法就是将animate定义为

def animate(i, u=u):
    ...

这明确地将u的副本传递给animate