[英]Issues with passing variables inside a class - python
我在類波紋管中遇到了方法動畫的實現問題。 動畫方法旨在創建波傳播的動畫。 我不希望animation方法修改Wave對象的狀態實例變量u,因此,我試圖在animation方法中創建局部變量u。 不過,我不知道如何從被動畫方法內部定義的動畫功能動畫方法通過局部變量u。 從我的構想來看,按照我嘗試實現的方式, 動畫方法的局部變量u應該是動畫方法(在動畫方法內部定義)的全局變量之王。 但是,這種假設顯然是錯誤的,否則我不會得到任何錯誤。 作為補充信息,我得到的錯誤是: 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中的異常(最近一次調用最近):文件“ /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”,lin e 201,具有動畫效果un = u.copy()UnboundLocalError:賦值之前引用了本地變量'u'Tkinter回調回調中的異常Traceback(最近一次調用):文件“ /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(自己)文件“ /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/ _draw_next_frame self._draw_frame(framedata)文件“ /usr/lib/pymodules/python2.7/matplotlib/animation.py”中的第754行,位於matplotlib / animation.py”行中 e 1049,在_draw_frame中self._drawn_artists = self._func(framedata,* self._args)文件“ wave.py”,第201行,帶有動畫un = u.copy()UnboundLocalError:賦值前引用了局部變量'u'
當您在Python中使用閉包捕獲變量時,不允許您對其進行賦值。 如果Python看到您已分配給它,則不允許從封閉范圍中捕獲它; 它必須是一個新的函數局部變量(對於animate
函數是局部的)。 但是由於您正嘗試使用捕獲的u
進行初始化,因此需要u
的值,但是在這種情況下,Python決定u
必須是本地的才能進行animate
,因此它不會查看animate
的封閉范圍。 這就是為什么您會收到該錯誤的原因。
解決這個問題的一種簡單方法是將animate
定義為
def animate(i, u=u):
...
這顯式地將u
的副本傳遞給animate
。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.