Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 类如何生成根据类属性变化的回调函数?_Python_Class_Import_Wrapper_Python Module - Fatal编程技术网

Python 类如何生成根据类属性变化的回调函数?

Python 类如何生成根据类属性变化的回调函数?,python,class,import,wrapper,python-module,Python,Class,Import,Wrapper,Python Module,我有这样的情况: 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

我有这样的情况:

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
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?
main.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
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=a.getaudiocallback()
创建
f
,是否在其代码中保留指向
a.liverecording
的指针(因此,如果后者被修改,这将被考虑在内),或者保存
a.liverecording
值的副本(即
False
)在创建
f

时,如果您了解闭包,这里唯一的技巧是在闭包中捕获的局部变量是
getaudiocallback
中的
self
参数

在该方法中,
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
>f=a.getaudiocallback()
>>>f
>>>f.。\uuuu闭包\uuuu[0]。单元格内容
>>>f.。\uuuu闭包\uuuu[0]。单元格内容是
真的
如果
getaudiocallback
仍处于活动状态,并且它将
self
反弹到某个其他值,则
f.\uuu closure\uuu[0]
将更新为指向
self
的新值。既然它已经退出,那就永远不会发生;单元格将始终指向调用方法时位于
a
中的实例


但是如果该实例后来发生了变异,比如当您编写
a.liverecording=True
时,您当然可以看到。

第二个代码段不起作用的原因是因为您分配给
a.recording
,而不是
a.liverecording
。第一个可能与pyAudio有关。就类和闭包而言,您所做的是完全正确的。正如@aranfey所指出的,如果使用正确的变量名,它实际上在非pyaudio示例中工作得很好。因此,实际问题(假设不是类似的打字错误)可能是pyaudio特有的。例如,您是否知道您的回调正在被调用?(如果您添加
else:print('not recording')
,会发生什么情况?)@Basj您是在问
f
如何最终成为捕获
self
的闭包,还是需要一个关于闭包是什么以及它们如何工作的完整教程?回答了您的问题吗?我看不出有什么区别。
n
是您的
自我
x
是您的
输入数据、帧计数、时间信息、状态