python使用dataclass数据类有个坑

2024-04-12 01:44

本文主要是介绍python使用dataclass数据类有个坑,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

今天在创建数据类时,遇到一个问题。发现数据出现了问题。代码如下:


from dataclasses import dataclass
@dataclass
class InPut:start:bool = Falsestop:bool = 0fault:bool = Noneinterval:int = 0@dataclass
class OutPut:星启动:bool = None主启动:bool = None三角启动:bool = None@dataclass
class Temp():...@dataclass
class Motor:input:InPut = InPut()outPut:OutPut = OutPut()temp:Temp = Temp()

上面创建了4个类,其中Motorl 里面的3个属性是由上面的3个数据类对象构成。这样Motor类就会很方便的操作输入和输出。然后分别写两个类,没个类属性保存Motor对象代码如下:


class Devices:motor1 = Motor()motor2 = Motor()motor3 = Motor()motor4 = Motor()motor5 = Motor()class HMI:input:InPut = InPut(interval=50)input2:InPut = InPut(interval=100)input3:InPut = InPut(interval=300)input4:InPut = InPut(interval=400)input5:InPut = InPut(interval=600)

在写个映射函数,把HMI类的数据映射给Devices类,代码如下:


def mapping():Devices.motor1.input.interval = HMI.input.intervalDevices.motor2.input.interval = HMI.input2.intervalDevices.motor3.input.interval = HMI.input3.intervalDevices.motor4.input.interval = HMI.input4.intervalDevices.motor5.input.interval = HMI.input5.intervalprint("motor1.input.interval:",Devices.motor1.input.interval)print("motor2.input.interval:",Devices.motor2.input.interval)print("motor3.input.interval:",Devices.motor3.input.interval)print("motor4.input.interval:",Devices.motor4.input.interval)print("motor5.input.interval:",Devices.motor5.input.interval)if __name__ == '__main__':mapping()

貌似没问题,打印结果如下:

motor1.input.interval: 600
motor2.input.interval: 600
motor3.input.interval: 600
motor4.input.interval: 600
motor5.input.interval: 600

结果都是600,怎么会这样?先把motor对象的ID打出来。


def mapping():Devices.motor1.input.interval = HMI.input.intervalDevices.motor2.input.interval = HMI.input2.intervalDevices.motor3.input.interval = HMI.input3.intervalDevices.motor4.input.interval = HMI.input4.intervalDevices.motor5.input.interval = HMI.input5.interval# print("motor1.input.interval:",Devices.motor1.input.interval)# print("motor2.input.interval:",Devices.motor2.input.interval)# print("motor3.input.interval:",Devices.motor3.input.interval)# print("motor4.input.interval:",Devices.motor4.input.interval)# print("motor5.input.interval:",Devices.motor5.input.interval)print("motor1",id(Devices.motor1))print("motor2",id(Devices.motor2))print("motor3",id(Devices.motor3))print("motor4",id(Devices.motor4))print("motor5",id(Devices.motor5))if __name__ == '__main__':mapping()#运行结果:
motor1 2213315589264
motor2 2213317258400
motor3 2213316869232
motor4 2213317974672
motor5 2213317975920
def mapping():Devices.motor1.input.interval = HMI.input.intervalDevices.motor2.input.interval = HMI.input2.intervalDevices.motor3.input.interval = HMI.input3.intervalDevices.motor4.input.interval = HMI.input4.intervalDevices.motor5.input.interval = HMI.input5.interval# print("motor1.input.interval:",Devices.motor1.input.interval)# print("motor2.input.interval:",Devices.motor2.input.interval)# print("motor3.input.interval:",Devices.motor3.input.interval)# print("motor4.input.interval:",Devices.motor4.input.interval)# print("motor5.input.interval:",Devices.motor5.input.interval)print("motor1.input",id(Devices.motor1.input))print("motor2.input",id(Devices.motor2.input))print("motor3.input",id(Devices.motor3.input))print("motor4.input",id(Devices.motor4.input))print("motor5.input",id(Devices.motor5.input))结果
motor1.input 2891784968080
motor2.input 2891784968080
motor3.input 2891784968080
motor4.input 2891784968080
motor5.input 2891784968080

上面的id是一样的,说明指向了同一个内存地址。这里就有一个坑。

分析原因及解决办法如下:

在这个代码中,因为使用了`dataclass`的默认值初始化方式,会导致所有`Motor`类的实例都共享相同的`InPut`类的实例,从而导致它们的`id`都是相同的。如果希望每个`Motor`实例拥有独立的`InPut`实例,可以通过在`Motor`类的`__post_init__`方法中为`input`属性赋予新的`InPut`实例来实现。下方修改代码:

@dataclass
class Motor:input: InPut = NoneoutPut: OutPut = OutPut()temp: Temp = Temp()def __post_init__(self):if self.input is None:self.input = InPut()


通过在`Motor`类中定义`__post_init__`方法,可以确保每个`Motor`实例都有独立的`InPut`实例,从而使它们的`id`不再相同。

完整代码如下:


from dataclasses import dataclass
@dataclass
class InPut:start:bool = Falsestop:bool = 0fault:bool = Noneinterval:int = 0@dataclass
class OutPut:星启动:bool = None主启动:bool = None三角启动:bool = None@dataclass
class Temp():...@dataclass
class Motor:input:InPut = NoneoutPut:OutPut = OutPut()temp:Temp = Temp()def __post_init__(self):if self.input is None:self.input = InPut()class Devices:motor1 = Motor()motor2 = Motor()motor3 = Motor()motor4 = Motor()motor5 = Motor()class HMI:input:InPut = InPut(interval=50)input2:InPut = InPut(interval=100)input3:InPut = InPut(interval=300)input4:InPut = InPut(interval=400)input5:InPut = InPut(interval=600)def mapping():Devices.motor1.input.interval = HMI.input.intervalDevices.motor2.input.interval = HMI.input2.intervalDevices.motor3.input.interval = HMI.input3.intervalDevices.motor4.input.interval = HMI.input4.intervalDevices.motor5.input.interval = HMI.input5.intervalprint("motor1.input.interval:",Devices.motor1.input.interval)print("motor2.input.interval:",Devices.motor2.input.interval)print("motor3.input.interval:",Devices.motor3.input.interval)print("motor4.input.interval:",Devices.motor4.input.interval)print("motor5.input.interval:",Devices.motor5.input.interval)print("motor1.input",id(Devices.motor1.input))print("motor2.input",id(Devices.motor2.input))print("motor3.input",id(Devices.motor3.input))print("motor4.input",id(Devices.motor4.input))print("motor5.input",id(Devices.motor5.input))if __name__ == '__main__':mapping()

问题得以解决。

结果如下:

motor1.input.interval: 50
motor2.input.interval: 100
motor3.input.interval: 300
motor4.input.interval: 400
motor5.input.interval: 600
motor1.input 2353790703552
motor2.input 2353793639328
motor3.input 2353793640240
motor4.input 2353793638944
motor5.input 2353793639808

这篇关于python使用dataclass数据类有个坑的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/895764

相关文章

Python Pandas高效处理Excel数据完整指南

《PythonPandas高效处理Excel数据完整指南》在数据驱动的时代,Excel仍是大量企业存储核心数据的工具,Python的Pandas库凭借其向量化计算、内存优化和丰富的数据处理接口,成为... 目录一、环境搭建与数据读取1.1 基础环境配置1.2 数据高效载入技巧二、数据清洗核心战术2.1 缺失

java中XML的使用全过程

《java中XML的使用全过程》:本文主要介绍java中XML的使用全过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录什么是XML特点XML作用XML的编写语法基本语法特殊字符编写约束XML的书写格式DTD文档schema文档解析XML的方法​​DOM解析XM

使用Java实现Navicat密码的加密与解密的代码解析

《使用Java实现Navicat密码的加密与解密的代码解析》:本文主要介绍使用Java实现Navicat密码的加密与解密,通过本文,我们了解了如何利用Java语言实现对Navicat保存的数据库密... 目录一、背景介绍二、环境准备三、代码解析四、核心代码展示五、总结在日常开发过程中,我们有时需要处理各种软

利用Python实现Excel文件智能合并工具

《利用Python实现Excel文件智能合并工具》有时候,我们需要将多个Excel文件按照特定顺序合并成一个文件,这样可以更方便地进行后续的数据处理和分析,下面我们看看如何使用Python实现Exce... 目录运行结果为什么需要这个工具技术实现工具的核心功能代码解析使用示例工具优化与扩展有时候,我们需要将

使用Nginx配置文件服务器方式

《使用Nginx配置文件服务器方式》:本文主要介绍使用Nginx配置文件服务器方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 为什么选择 Nginx 作为文件服务器?2. 环境准备3. 配置 Nginx 文件服务器4. 将文件放入服务器目录5. 启动 N

使用nohup和--remove-source-files在后台运行rsync并记录日志方式

《使用nohup和--remove-source-files在后台运行rsync并记录日志方式》:本文主要介绍使用nohup和--remove-source-files在后台运行rsync并记录日... 目录一、什么是 --remove-source-files?二、示例命令三、命令详解1. nohup2.

Python+PyQt5实现文件夹结构映射工具

《Python+PyQt5实现文件夹结构映射工具》在日常工作中,我们经常需要对文件夹结构进行复制和备份,本文将带来一款基于PyQt5开发的文件夹结构映射工具,感兴趣的小伙伴可以跟随小编一起学习一下... 目录概述功能亮点展示效果软件使用步骤代码解析1. 主窗口设计(FolderCopyApp)2. 拖拽路径

Qt之QMessageBox的具体使用

《Qt之QMessageBox的具体使用》本文介绍Qt中QMessageBox类的使用,用于弹出提示、警告、错误等模态对话框,具有一定的参考价值,感兴趣的可以了解一下... 目录1.引言2.简单介绍3.常见函数4.按钮类型(QMessage::StandardButton)5.分步骤实现弹窗6.总结1.引言

Python使用Reflex构建现代Web应用的完全指南

《Python使用Reflex构建现代Web应用的完全指南》这篇文章为大家深入介绍了Reflex框架的设计理念,技术特性,项目结构,核心API,实际开发流程以及与其他框架的对比和部署建议,感兴趣的小伙... 目录什么是 ReFlex?为什么选择 Reflex?安装与环境配置构建你的第一个应用核心概念解析组件

Qt中Qfile类的使用

《Qt中Qfile类的使用》很多应用程序都具备操作文件的能力,包括对文件进行写入和读取,创建和删除文件,本文主要介绍了Qt中Qfile类的使用,具有一定的参考价值,感兴趣的可以了解一下... 目录1.引言2.QFile文件操作3.演示示例3.1实验一3.2实验二【演示 QFile 读写二进制文件的过程】4.