首页 > 其他分享 >深拷贝、浅拷贝、直接复制的区别

深拷贝、浅拷贝、直接复制的区别

时间:2024-04-14 20:44:06浏览次数:22  
标签:__ 区别 self tag 复制 dt2 拷贝 dt

深拷贝、浅拷贝、直接复制的区别

不妨举一个例子,有一个名为Date的类和一个名为Time的类,如下定义:

class Date:
    def __init__(self, year, month, day):
        self.year = year
        self.month = month
        self.day = day

    def __str__(self):
        return f"{self.year}-{self.month}-{self.day}"


class Time:
    def __init__(self, hour, minute, second):
        self.hour = hour
        self.minute = minute
        self.second = second
    
    def __str__(self):
        return f"{self.hour}:{self.minute}:{self.second}"

现在我们再定义一个名为Datetime的类:

class Datetime:
    def __init__(self, date, time, tag: str):
        self.date = date
        self.time = time
        self.tag = tag
    
    def __str__(self):
        return f"{self.tag} {self.date} {self.time}"

现在我们创建一个Datetime对象:

dt = Datetime(Date(2024, 1, 1), Time(0, 0, 0), "example1")

接下来考虑:如何复制这个对象?

直接赋值

最容易想到的方法就是直接赋值,如下:

dt2 = dt

此时我们对dt2进行一下修改,将它的tag改成"example2",看一下会发生什么:

dt2.tag = "example2"
print(dt)
print(dt2)

输出:

example2 2024-1-1 0:0:0
example2 2024-1-1 0:0:0

可以看到这两个对象的tag属性都已经被修改为了"example2",这是因为直接赋值时,Python会把dt1dt2这两个名字指向同一个对象。

浅拷贝

浅拷贝可以用copy.copy()实现,修改上述代码:

from copy import copy

dt = Datetime(Date(2024, 1, 1), Time(0, 0, 0), "example1")
dt2 = copy(dt)
dt2.tag = "example2"
print(dt)
print(dt2)

输出:

example1 2024-1-1 0:0:0
example2 2024-1-1 0:0:0

可以看到,dt2tag属性被修改了,但是dttag属性没有被修改。但是当我们将d2修改为2023年1月1日:

dt2.date.year = 2023
print(dt)
print(dt2)

输出:

example1 2023-1-1 0:0:0
example2 2023-1-1 0:0:0

可以看到,dtdate属性也被修改了,这是因为浅拷贝不会处理更深层的属性。这时我们可以用深拷贝:

深拷贝

深拷贝可以用copy.deepcopy()实现,修改上述代码:

from copy import deepcopy

dt = Datetime(Date(2024, 1, 1), Time(0, 0, 0), "example1")
dt2 = deepcopy(dt)
dt2.tag = "example2"
dt2.date.year = 2023
print(dt)
print(dt2)

输出:

example1 2024-1-1 0:0:0
example1 2023-1-1 0:0:0

可以看到,dt2date属性没有被修改,这是因为深拷贝会递归地处理更深层的属性。深拷贝下的dtdt2可以看作完全无关。

标签:__,区别,self,tag,复制,dt2,拷贝,dt
From: https://www.cnblogs.com/normal-pcer/p/18134594/240414_about_deepcopy

相关文章

  • 13-axios 传递参数的方式(data 与 params 的区别)
    Axios官方网址:起步|Axios中文文档|Axios中文网(axios-http.cn)参考文章:axios传递参数的方式(data与params的区别)-知乎(zhihu.com) Axiosa大家都非常的清楚,一个既可以用于客户端或者 服务端发送http请求的库。但是在前后端联调的时候有的时候会很难受,所以这里我......
  • eBPF xdp和tc区别
     xdptc层次网卡驱动层数据链路层位置进入Linux网络协议栈之前在Linux网络协议栈中方向只有ingress有ingress和egress修改支持修改报文支持修改报文,有skb结构,修改更方便cilium加载eBPF到虚拟网卡tc上来实现流量转发。......
  • Java中的matches()方法与find()方法区别
    正则表达式用于在字符串中进行模式匹配。在处理字符串时,经常需要使用matches()方法和find()方法来查找与正则表达式匹配的部分。虽然它们都用于匹配字符串,但有一些重要的区别。matches()方法matches()方法是String类中的一个方法,用于判断整个字符串是否与给定的正则表达......
  • 【Qt】编写的qt程序,如何把依赖的dll自动拷贝到exe同级目录
    如果你的Qt程序在VisualStudio中可以正常启动但直接启动exe文件会报错,可能是因为缺少依赖的QtDLL文件导致的。为了确定缺少了哪些DLL文件,你可以尝试以下方法:使用DependencyWalker:DependencyWalker是一个工具,可以帮助你分析可执行文件的依赖关系,并找出缺失的D......
  • Python教程:return和yield的区别
    return一直中,每中语言中其没没有很大差别,就不多说了。(shell语言return的是退出状态,可能差别是比较大的)最早看到yield应该是哪们语言用来调整什么线程优先级的,记不清了,不过那里的yield和python中的yield应该功能有区别。一、return和yield的异同共同点:return和yield都用来返回值......
  • Sql Server对等复制中将截断字符串或二进制数据。 (源: MSSQLServer,错误号: 8152)
    近期发现好好的复制突然出现了报错,导致备份库数据不一致的问题,如下 一直以为是发布数据库进行了DDL操作没有同步到这边来,导致数据同步时长度不够导致的,结果把表都检查了一遍也没发现啥不对劲最后只好去找相关资料,结果找到了官方资料(目前老项目用的14版本) 这边有几个......
  • java的两个bean之间复制属性,所有属性中替换某几个字符
    以下是实现代码:importjava.beans.PropertyDescriptor;importjava.lang.reflect.InvocationTargetException;importjava.util.ArrayList;importjava.util.List;importorg.springframework.beans.BeanUtils;publicclassBeanCopyUtil{/***复制bean属性......
  • linux环境安装——mysql集群安装复习——主从复制
    1、首先安装mysql: mkdir-p/soft/mysql8mkdir-p/evir/mysql8执行上传文件操作rpm-qa|grepmariadb查询是否有这个文件rpm-e--nodepsmariadb-libs进行删除rpm-qa|grepmariadb查询这个文件是否删干净tar-xf/soft/my......
  • 数据库物理删除和逻辑删除的区别 ?
    一、主要区别:物理删除和软删除是数据库中常见的两种数据删除方式,它们的主要区别在于数据的处理方式和是否永久删除数据。 二、概念:物理删除:物理删除是指从数据库中彻底删除数据,包括数据记录和关联的索引等,使其完全消失。物理删除释放了存储空间,并且被删除的数据无法再......
  • mysql半同步复制
    1、首先在master上面安装插件INSTALLPLUGINrpl_semi_sync_masterSONAME'semisync_master.so';QueryOK,0rowsaffected(0.01sec)2、设置master全局变量和超时时间SETGLOBALrpl_semi_sync_master_enabled=1;QueryOK,0rowsaffected(0.00sec)查看变量是否开......