首页 > 编程问答 >Python 无法 pickle 自定义类型

Python 无法 pickle 自定义类型

时间:2024-07-24 12:22:49浏览次数:14  
标签:python pickle

我正在尝试在 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}"

解释:

  1. 将生成器结果转换为列表: 在工作进程中,我们将生成器的结果转换为列表 ( result = list(my_gen) )。列表是可 pickle 的,因此可以安全地通过队列发送。

  2. 在主进程中重新创建生成器: 如果需要在主进程中使用生成器,可以使用列表的结果重新创建它。

其他方法:

  • 使用其他进程间通信机制: 除了队列之外,还可以使用其他进程间通信机制,例如管道或共享内存,这些机制可能支持生成器。
  • 重构代码: 如果可能,请考虑重构代码,以便工作函数不返回生成器。

请注意,pickle 有其局限性,并且不适用于所有类型的对象。如果遇到其他 pickle 错误,则可能需要探索其他方法或使用不同的序列化技术。

标签:python,pickle
From: 78786345

相关文章

  • python 语法无效?
    我试图编写一些Python代码,但由于某些奇怪的原因,它重复了无效的语法,我不知道最大的问题是什么。这些行是文件中唯一的代码行。Age=int(input("Howoldareyou?:"))ifAge>=18:print("YouareaAdult!")我尝试更改行,因为这似乎是我的生气,但它没有做任何帮......
  • 如何在Python的matplotlib中将条形标签绘制到右侧并为条形标签添加标题?
    我已经在python中的matplotlib中创建了一个图表,但是以下代码中的最后一行不允许在图表之外对齐条形标签。importmatplotlib.pyplotaspltg=df.plot.barh(x=name,y=days)g.set_title("Dayspeopleshowedup")g.bar_label(g.containers[0],label_type='edge')我得......
  • 19、Python之容器:快来数一数,24678?Counter能数得更好
    引言关于数据的分组计数,前面的文章中已经涉及了很多次。眼下要进行分组计数,我们可用的方法有:1、直接使用dict进行计数,需要对首次出现的键进行判断初始化的操作;2、使用dict的setdefault()方法进行计数,代码可以简化一些,虽然方法名有点怪;3、defaultdict进行计数,可以设置自动......
  • 如何使用 C# 检查用户是否安装了最低 Python 版本并且可以访问我的代码?
    我正在开发一个C#程序,该程序必须为一项特定任务运行一些Python代码。(Python代码很复杂,是由另一个团队开发的。无法在C#中重现其功能。)我正在尝试更新我的程序的安装程序文件以解决此问题:我希望它检查用户是否(谁正在安装我的程序)已安装Python并且它满足我的最低版......
  • 如何优雅地将复杂的Python对象和SQLAlchemy对象模型类结合起来?
    我有一个相当复杂的类,具有从提供的df到init计算的复杂属性,这些属性可能是最终可以序列化为字符串的其他类类型。在Python中,我想处理对象而不是原始类型,但也想使用SQLAlchemy与数据库交互。表中的列与许多类属性相同,如何优雅地组合这两个类?我可以使用组合并将数据......
  • Python Match Case:检查未知长度的可迭代内部的类型
    我想使用匹配大小写检查一个未知长度的迭代(假设为list)仅包含给定类型(假设为float)(还有其他情况,只有这个给我带来了问题)。case[*elems]ifall([isinstance(elem,float)foreleminelems]):returnnum这个似乎可行,但确实很不Pythony。看来应该有更简单的方法。......
  • Python实现excel数据的读取和写入
    1.安装说到前面的话,实现excel文件数据的读取和写入,在python中还有其它方法,比如说pandas。鉴于最近粉丝朋友问到上面的“xlrd”和“xlwt”,那么笔者下面将通过这两个方法,来实现excel文件数据的读取和写入。首先,我们先需要提前安装好对应的库。需要注意的是,xlrd从2.0版本开始,只......
  • python_进程与线程_多线程
    一、程序与进程的概念1、进程:指启动后的程序,系统会为进程分配内存空间二、创建进程的方式1、第一种创建进程的方式process(group=None,target,name,args,kwargs)group:表示分组,实际上不使用,默认为None即可target:表示子进程要执行的任务,支持函数名name:表示子进程的......
  • python_网络编程_socket
    一、网络编程的基本概念通信协议:internet协议,任何私有网络支持此协议,就可以接入互联网二、七层协议与四层协议从下到上分别是:物理层、数据链路层、网络层、传输层、会话层、表示层、应用层三、掌握TCP、IP协议ip协议是整个TCP、IP协议族的核心IP地址就是会联网上计算......
  • 你能对 Python 类型注释进行模式匹配吗?
    你能在Python类型上进行模式匹配吗?我见过简单的例子:importbuiltinsmatchx:casebuiltins.str:print("matchedstr")casebuildins.int:print("matchedint")但我想在嵌套类型上进行模式匹配,比如Annotated[Optional[Literal["a",......