我正在尝试在 ProcessPool 中运行一个函数,该函数将通过读取 python 文件并运行生成的类中的方法来加载一些自定义类。
我遇到的错误是
TypeError: cannot pickle 'generator' object
该方法需要返回一个生成器。我该如何解决这个问题,谢谢。
我用谷歌搜索但没有运气。
import pickle
from multiprocessing import Process, Queue
# 自定义类
class MyClass:
def __init__(self, name):
self.name = name
def my_generator(self):
for i in range(5):
yield f"{self.name} {i}"
# 工作函数
def worker_function(queue, filename):
# 从文件中加载类
with open(filename, "rb") as f:
code = compile(f.read(), filename, "exec")
exec(code, globals())
# 创建类的实例
my_instance = MyClass("Example")
# 获取生成器
my_gen = my_instance.my_generator()
# 将生成器的结果转换为列表
result = list(my_gen)
# 将结果放入队列
queue.put(result)
if __name__ == "__main__":
# 创建队列
queue = Queue()
# 创建进程
process = Process(target=worker_function, args=(queue, "my_class.py"))
# 启动进程
process.start()
# 从队列中获取结果
result = queue.get()
# 打印结果
print(result)
# 等待进程完成
process.join()
my_class.py 文件包含以下内容:
# 自定义类
class MyClass:
def __init__(self, name):
self.name = name
def my_generator(self):
for i in range(5):
yield f"{self.name} {i}"
解释:
-
将生成器结果转换为列表: 在工作进程中,我们将生成器的结果转换为列表 (
result = list(my_gen)
)。列表是可 pickle 的,因此可以安全地通过队列发送。 -
在主进程中重新创建生成器: 如果需要在主进程中使用生成器,可以使用列表的结果重新创建它。
其他方法:
- 使用其他进程间通信机制: 除了队列之外,还可以使用其他进程间通信机制,例如管道或共享内存,这些机制可能支持生成器。
- 重构代码: 如果可能,请考虑重构代码,以便工作函数不返回生成器。
请注意,pickle 有其局限性,并且不适用于所有类型的对象。如果遇到其他 pickle 错误,则可能需要探索其他方法或使用不同的序列化技术。
标签:python,pickle From: 78786345