You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python多进程调用类方法:序列化及BaseProcess._Popen参数错误求助

Python多进程调用类方法的问题根源与规范实现

问题根源

1. 标准multiprocessing的cannot pickle '_io.TextIOWrapper' object错误

Python多进程间传递对象必须先序列化,标准库multiprocessing默认用pickle做序列化工具,但pickle无法处理部分特殊对象,比如打开的文件句柄(_io.TextIOWrapper)。你在主进程初始化的类实例里如果包含这类对象,当把实例传给子进程时,就会触发序列化失败的错误。

2. multiprocess库的TypeError: BaseProcess._Popen() takes 1 positional argument but 2 were given错误

multiprocess库是标准multiprocessing的扩展,用dill替代pickle支持更多对象序列化,但你错误地导入了内部基类BaseProcess当作Process使用。BaseProcess的_Popen方法参数设计和标准库的Process完全不同,直接按标准Process的方式传参,就会出现参数不匹配的报错。而multiprocess.Process是库封装好的、兼容标准库接口的类,用它才能正常启动子进程。

规范实现方式

方式一:使用标准multiprocessing(规避不可序列化对象)

如果要坚持用标准库,需确保类实例不含pickle无法序列化的对象,常见处理方式:

  • 不在类实例中存储打开的文件句柄、网络连接等资源,改为在子进程方法内部按需创建/打开
  • 若必须传递相关资源,只传路径、配置等可序列化的参数,让子进程自行初始化资源

示例代码:

import multiprocessing

class MyClass:
    def __init__(self, file_path):
        # 仅存储文件路径,不存打开的文件对象
        self.file_path = file_path

    def worker(self):
        # 子进程内打开文件并操作
        with open(self.file_path, 'r') as f:
            print(f.readline())

if __name__ == '__main__':
    obj = MyClass('test.txt')
    p = multiprocessing.Process(target=obj.worker)
    p.start()
    p.join()

方式二:使用multiprocess库(支持更多序列化场景)

如果类实例必须包含pickle无法处理的对象,使用multiprocess库时必须导入正确的Process类,而非内部的BaseProcess:

示例代码:

import multiprocess

class MyClass:
    def __init__(self):
        # 即使包含TextIOWrapper,dill也能完成序列化
        self.f = open('test.txt', 'r')

    def worker(self):
        print(self.f.readline())
        self.f.close()

if __name__ == '__main__':
    obj = MyClass()
    # 必须使用multiprocess.Process,不能用BaseProcess
    p = multiprocess.Process(target=obj.worker)
    p.start()
    p.join()

注意:无论用哪种方式,都必须在if __name__ == '__main__':代码块中启动子进程,避免Windows系统下出现递归创建进程的问题(Python 3.11同样需要遵守该规则)。

内容的提问来源于stack exchange,提问作者hhharsha36

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 08:20:50