MATLAB使用parfeval传递Python对象报错 有无无需重写类的解法
问题原因
parfeval启动的工作进程运行独立的MATLAB实例,每个实例对应独立的Python解释器环境,主进程中创建的Python对象是仅属于主进程Python解释器的句柄,传输到子进程后无法被识别,因此触发Invalid or deleted object报错,并非parfeval存在参数类型限制。
无需修改Python类的解决方案
方案1:子进程内初始化Python实例(推荐)
将Python类初始化需要的可序列化参数(如api_key、OAuth凭证字符串、日志配置参数等)直接传递给parfeval,在执行函数内部完成Python类实例的创建,从根源避免跨进程传递Python对象的问题。
示例逻辑如下:
% 主进程仅传递初始化需要的可序列化参数 api_key = "your_api_key"; oauth_token = "your_oauth_token"; f = parfeval(@testFunc, 1, api_key, oauth_token); fetchOutputs(f)
function t = testFunc(api_key, oauth_token) % 子进程内部初始化Python Client实例 client = py.YourClientModule.Client(pyargs('api_key', api_key, 'oauth_token', oauth_token)); % 正常调用实例的属性、方法即可 t = client.get('soup'); end
该方案兼容性最好,即使Python实例包含不可序列化的活跃资源(如已建立的网络连接、打开的文件句柄)也可正常运行。
方案2:通过Python pickle序列化传递实例
如果你的Python类本身支持pickle序列化(大部分标准实现的Python类默认支持),可以在主进程将实例序列化为字节流后传递给子进程,子进程反序列化还原实例即可使用。
示例逻辑如下:
% 主进程初始化Python实例后序列化 o = py.YourClientModule.Client(pyargs('api_key', 'xxx', 'oauth_session', oauth_session)); pickled_obj = py.pickle.dumps(o); % 传递序列化后的字节流 f = parfeval(@testFunc, 1, pickled_obj); fetchOutputs(f)
function t = testFunc(pickled_obj) % 子进程反序列化还原实例 client = py.pickle.loads(pickled_obj); % 正常使用实例即可 t = client{'soup'}; end
注意:如果实例包含不可序列化的资源(如实时TCP连接、临时文件句柄),pickle操作会失败,这种情况请使用方案1。
内容的提问来源于stack exchange,提问作者dleal
相关产品推荐
相关产品推荐

