首页 文章

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

提问于
浏览
0

我正面临着从类波波纹中实现方法动画的问题 . 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 回答

  • 2

    在Python中使用闭包捕获变量时,不允许分配给它 . 如果Python看到你分配给它,那么就不允许从封闭范围中捕获它;它必须是一个新的函数局部变量( animate 函数的本地变量) . 但是既然你正在尝试使用捕获的_2530169来初始化它,你需要 u 的值,但是在这个上下文中Python决定 u 必须是 animate 的本地,所以它不是在看 animate 's enclosing scope. That'为什么你得到那个错误 .

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

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

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

相关问题