我有这种情况:module1.py
:
class AudioEngine:
def __init__(self):
self.liverecording = False
def getaudiocallback(self):
def audiocallback(in_data, frame_count, time_info, status): # these 4 parameters are requested by pyaudio
data = None # normally here we process the audio data
if self.liverecording:
print("Recording...")
return data
return audiocallback
main.py
:import module1
a = module1.AudioEngine()
f = a.getaudiocallback()
f(0, 0, 0, 0)
a.liverecording = True
f(0, 0, 0, 0) # prints "Recording...", which is the expected behaviour, but why does it work?
问题:如何使回调函数
audiocallback(...)
相应地更改为a.liverecording
的新值?如果开箱即用,为什么呢?更具体地说,一旦使用
f
创建的f = a.getaudiocallback()
是否在其代码中保留了指向a.liverecording
的指针(因此,如果修改了后者,则将其考虑在内)或a.liverecording
值的副本。 >(即False
)在创建f
时的时间? 最佳答案
如果您了解闭包,那么这里的唯一技巧就是在闭包中捕获的局部变量是self
中的getaudiocallback
参数。
在该方法内部,self
当然是AudioEngine
实例a
。因此,您捕获的变量的值就是该实例。
实际上,Python使您可以在运行时反思几乎所有内容,因此您可以直接看到以下内容:
>>> f = a.getaudiocallback()
>>> f
<function __main__.AudioEngine.getaudiocallback.<locals>.audiocallback(in_data, frame_count, time_info, status)>
>>> f.__closure__[0].cell_contents
<__main__.AudioEngine at 0x11772b3c8>
>>> f.__closure__[0].cell_contents is a
True
如果
getaudiocallback
仍然存在,并且将self
反弹到其他某个值,则该f.__closure__[0]
将更新为指向self
的新值。既然已经退出,那将永远不会发生。单元格将始终指向调用该方法时位于a
中的实例。但是,如果后来该实例发生了变异(例如编写
a.liverecording = True
时),您当然可以看到它。关于python - 类如何生成根据类属性更改的回调函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/50092205/