您的代码 _分配给pt
_in callback
;Python在编译时确定名称的范围,赋值使其成为本地名称。
pt = pt + frame_count
除非您另外告诉Python,否则就是这样。在Python 2中,您只能将名称明确标记为,global
而您需要Python 3才能使用nonlocal
关键字:
def callback(in_data, frame_count, time_info, status):
"""
This is the callback function for sound API
In each call, synthesized data is dumpped into the sound buffer
"""
nonlocal pt
wave = np.ndarray((frame_count, 2))
for i in range(frame_count):
ind = (i+pt) % n
wave[i,0] = float(x[ind]) * 2
wave[i,1] = float(y[ind]) * 2
pt = pt + frame_count
return (encode(wave), pyaudio.paContinue)
在这nonlocal pt
行代码中,明确告知Python不要将其pt
视为本地名称,而应从其封闭范围内取用get_audio_callback
。
在Python 2中,您可以创建一个从闭包中获取其值的本地:
def callback(in_data, frame_count, time_info, status):
"""
This is the callback function for sound API
In each call, synthesized data is dumpped into the sound buffer
"""
pt_local = pt
wave = np.ndarray((frame_count, 2))
for i in range(frame_count):
ind = (i+pt_local) % n
wave[i,0] = float(x[ind]) * 2
wave[i,1] = float(y[ind]) * 2
pt_local = pt_local + frame_count
return (encode(wave), pyaudio.paContinue)
因为您的封闭get_audio_callback
范围似乎仍然无法使用pt
, 并且不需要访问更新后的pt_local
值。
如果确实需要pt
在get_audio_callback
范围内进行更新(例如,如果callback
多次调用,并且需要在每次pt
调用之间进行更新),则需要避免pt
在callback
函数内部完全用作局部变量。
一种有效的解决方法是将值包装在可变对象中,或将其分配为可变属性,以使封闭范围和本地范围都可以访问该值,而不会将其视为本地赋值。在callback
函数上设置属性是实现此目的的一种好方法:
def get_audio_callback(pt):
def callback(in_data, frame_count, time_info, status):
"""
This is the callback function for sound API
In each call, synthesized data is dumpped into the sound buffer
"""
wave = np.ndarray((frame_count, 2))
for i in range(frame_count):
ind = (i+callback.pt) % n
wave[i,0] = float(x[ind]) * 2
wave[i,1] = float(y[ind]) * 2
callback.pt = callback.pt + frame_count
return (encode(wave), pyaudio.paContinue)
callback.pt = pt
return callback