0

0

如何在基于抽象基类的类中正确使用 pathos 多进程访问实例属性

聖光之護

聖光之護

发布时间:2026-01-07 14:49:30

|

695人浏览过

|

来源于php中文网

原创

如何在基于抽象基类的类中正确使用 pathos 多进程访问实例属性

当使用 `pathos.multiprocessing.processpool` 在继承自抽象基类(abc)的 `attr` 类中并行调用方法时,子进程无法访问主进程中动态设置的实例属性(如 `self.series1`),导致 `attributeerror`;根本原因是多进程间对象序列化/反序列化时未完整传递实例状态,需显式传递所需数据。

在 Python 多进程编程中,尤其是使用 pathos(基于 dill 序列化)时,一个常见但易被忽视的陷阱是:子进程并不共享父进程的内存空间,也不会自动重建类实例的完整运行时状态。即使 dill 支持序列化闭包、lambda 和部分实例状态,它仍可能无法可靠地捕获在 plot_series() 中动态挂载到 self 上的属性(例如 self.series1, self.series2),尤其当该类继承自 abc.ABC 且使用 @define(来自 attrs)时——attrs 的 __slots__=False 虽允许动态属性,但 dill 在跨进程反序列化 MyPlot 实例时,往往只还原了 __init__ 初始化的字段(如 x),而忽略后续赋值的属性。

✅ 正确解法:显式传递计算所需数据

最稳健、可维护的方案是避免跨进程传递整个实例,转而将依赖的计算结果(即 plot_series() 生成的数组)以纯数据结构(如字典、命名元组或 AttrDict)形式序列化后传入子进程:

DALL·E 2
DALL·E 2

OpenAI基于GPT-3模型开发的AI绘图生成工具,可以根据自然语言的描述创建逼真的图像和艺术。

下载
class AttrDict(dict):
    """支持点号访问的字典,便于保持代码可读性"""
    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.__dict__ = self

@define(slots=False)
class MyPlot(GenericPlot):
    def plot_series(self):
        self.series1 = np.sin(self.x)
        self.series2 = np.cos(self.x)
        self.series3 = np.tan(self.x)

    def create_figure1(self, attr_dict):
        fig, ax = plt.subplots(figsize=(12, 3))
        ax.plot(attr_dict["series1"], label="sin(x)")
        ax.plot(attr_dict["series2"], label="cos(x)")
        ax.legend()
        plt.close(fig)  # 避免内存泄漏
        return fig

    # create_figure2 / create_figure3 同理,仅使用 attr_dict 中的数据

    def generate_figures(self):
        # ✅ 关键步骤:在主进程完成数据准备,并封装为可序列化对象
        self.plot_series()  # 确保先计算
        attr_dict = AttrDict({
            "series1": self.series1,
            "series2": self.series2,
            "series3": self.series3,
            "x": self.x  # 如需也可传入原始 x
        })

        pool = ProcessPool(nodes=3)
        methods = [self.create_figure1, self.create_figure2, self.create_figure3]

        # 每个子任务接收 (method, attr_dict),无需绑定 self
        tasks = [(method, attr_dict) for method in methods]
        results = pool.map(parallel_process_function, tasks)

        figures, image_arrays = zip(*results)
        return list(figures), list(image_arrays)

⚠️ 注意事项与最佳实践

  • 不要依赖 self 在子进程中可用:pathos 并非万能,尤其对含复杂状态、Matplotlib 对象或抽象方法约束的类,dill 反序列化行为不可靠。
  • 优先使用纯函数 + 显式参数:将绘图逻辑重构为接受 attr_dict 或 dataclass 实例的无状态函数,提升可测试性与可移植性。
  • 显式关闭 figure:务必在每个子进程内调用 plt.close(fig) 或 plt.close('all'),否则可能导致资源泄漏或 RuntimeError: main thread is not in main loop。
  • 避免 slots=True 与动态属性冲突:@define(slots=True) 会禁止动态属性赋值(如 self.series1 = ...),因此必须使用 slots=False(已正确配置)。
  • 考虑替代方案:若逻辑复杂度允许,可改用 concurrent.futures.ProcessPoolExecutor + functools.partial 预绑定参数,语义更清晰。

✅ 总结

该问题本质不是 abc.ABC 或 attrs 的缺陷,而是多进程模型下“对象状态不可自动共享”的必然体现。解决方案不在于绕过抽象基类,而在于遵循函数式并发原则:输入确定、副作用隔离、数据显式传递。通过将 plot_series() 的输出封装为轻量、可序列化的 AttrDict 并传入子进程,既保留了面向对象的设计意图(抽象接口、职责分离),又确保了多进程执行的健壮性与可预测性。

热门AI工具

更多
DeepSeek
DeepSeek

幻方量化公司旗下的开源大模型平台

豆包大模型
豆包大模型

字节跳动自主研发的一系列大型语言模型

通义千问
通义千问

阿里巴巴推出的全能AI助手

腾讯元宝
腾讯元宝

腾讯混元平台推出的AI助手

文心一言
文心一言

文心一言是百度开发的AI聊天机器人,通过对话可以生成各种形式的内容。

讯飞写作
讯飞写作

基于讯飞星火大模型的AI写作工具,可以快速生成新闻稿件、品宣文案、工作总结、心得体会等各种文文稿

即梦AI
即梦AI

一站式AI创作平台,免费AI图片和视频生成。

ChatGPT
ChatGPT

最最强大的AI聊天机器人程序,ChatGPT不单是聊天机器人,还能进行撰写邮件、视频脚本、文案、翻译、代码等任务。

相关专题

更多
typedef和define区别
typedef和define区别

typedef和define区别在类型检查、作用范围、可读性、错误处理和内存占用等。本专题为大家提供typedef和define相关的文章、下载、课程内容,供大家免费下载体验。

118

2023.09.26

define的用法
define的用法

define用法:1、定义常量;2、定义函数宏:3、定义条件编译;4、定义多行宏。更多关于define的用法的内容,大家可以阅读本专题下的文章。

360

2023.10.11

go语言 面向对象
go语言 面向对象

本专题整合了go语言面向对象相关内容,阅读专题下面的文章了解更多详细内容。

57

2025.09.05

java面向对象
java面向对象

本专题整合了java面向对象相关内容,阅读专题下面的文章了解更多详细内容。

62

2025.11.27

lambda表达式
lambda表达式

Lambda表达式是一种匿名函数的简洁表示方式,它可以在需要函数作为参数的地方使用,并提供了一种更简洁、更灵活的编码方式,其语法为“lambda 参数列表: 表达式”,参数列表是函数的参数,可以包含一个或多个参数,用逗号分隔,表达式是函数的执行体,用于定义函数的具体操作。本专题为大家提供lambda表达式相关的文章、下载、课程内容,供大家免费下载体验。

214

2023.09.15

python lambda函数
python lambda函数

本专题整合了python lambda函数用法详解,阅读专题下面的文章了解更多详细内容。

192

2025.11.08

Python lambda详解
Python lambda详解

本专题整合了Python lambda函数相关教程,阅读下面的文章了解更多详细内容。

60

2026.01.05

treenode的用法
treenode的用法

​在计算机编程领域,TreeNode是一种常见的数据结构,通常用于构建树形结构。在不同的编程语言中,TreeNode可能有不同的实现方式和用法,通常用于表示树的节点信息。更多关于treenode相关问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

546

2023.12.01

Golang 测试体系与代码质量保障:工程级可靠性建设
Golang 测试体系与代码质量保障:工程级可靠性建设

Go语言测试体系与代码质量保障聚焦于构建工程级可靠性系统。本专题深入解析Go的测试工具链(如go test)、单元测试、集成测试及端到端测试实践,结合代码覆盖率分析、静态代码扫描(如go vet)和动态分析工具,建立全链路质量监控机制。通过自动化测试框架、持续集成(CI)流水线配置及代码审查规范,实现测试用例管理、缺陷追踪与质量门禁控制,确保代码健壮性与可维护性,为高可靠性工程系统提供质量保障。

48

2026.02.28

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
最新Python教程 从入门到精通
最新Python教程 从入门到精通

共4课时 | 22.5万人学习

Django 教程
Django 教程

共28课时 | 4.7万人学习

SciPy 教程
SciPy 教程

共10课时 | 1.8万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号