Python多进程报错:无法pickle<ufunc '<lambda> (vectorized)'>
问题分析与解决方案
问题根源
你遇到的PicklingError本质是Python多进程启动时需要序列化(pickle)整个类实例,但你的大类里包含了无法被pickle的lambda函数(错误信息里的<ufunc '<lambda> (vectorized)'>)。当调用Process(target=self.test)时,子进程需要传递整个类实例,而实例中的lambda无法被序列化,导致报错。把这两个方法放到小类里能正常执行,是因为小类没有这些不可pickle的属性。
解决办法
1. 把子进程逻辑抽成独立顶层函数
避免序列化整个类实例,直接让子进程调用独立函数:
# 定义在类外部的顶层函数 def test_func(): print("hji") class YourBigClass: def test2(self): p = Process(target=test_func) p.start() p.join()
2. 替换类中的lambda为可pickle的具名函数
lambda函数无法被pickle,把类里用到的vectorized lambda改成用def定义的普通函数:
class YourBigClass: # 替换原来的lambda为具名函数 def vectorized_func(self, x): # 原来lambda的逻辑 return x * 2 def test(self): print("hji") def test2(self): p = Process(target=self.test) p.start() p.join()
3. 让类支持自定义pickle
如果必须保留lambda或其他不可pickle属性,可以在类里定义__getstate__和__setstate__方法,手动控制序列化内容,排除不可pickle的属性:
class YourBigClass: def __init__(self): self.vectorized_lambda = np.vectorize(lambda x: x*2) # 假设这是那个不可pickle的lambda def __getstate__(self): # 复制实例状态,排除不可pickle的属性 state = self.__dict__.copy() del state['vectorized_lambda'] return state def __setstate__(self, state): # 恢复状态,重新初始化被排除的属性 self.__dict__.update(state) self.vectorized_lambda = np.vectorize(lambda x: x*2) def test(self): print("hji") def test2(self): p = Process(target=self.test) p.start() p.join()
4. Jupyter环境额外注意
确保你的类定义在单独的.py文件中,而非直接在Jupyter单元格里定义。Jupyter的命名空间特殊,直接在单元格定义的类可能会导致pickle时找不到正确的类引用。
内容的提问来源于stack exchange,提问作者KevinLester77
相关产品推荐
相关产品推荐

