Python 对象拷贝的那点事?

Python对象复制竟然有这么多种方式,赶紧学起来! 在Python中,对象的复制是一个常见需求,尤其是在处理复杂数据结构时。浅拷贝通过copy模块的copy()函数实现,它创建原始对象的一个新实例,但这个新实例内部的子对象仍然是对原对象子对象的引用。这节将深入探讨浅拷贝的工作原理,并通过实战示例展示其在列表与字典中的应用,同时指出使用过程中需要注意的共享引用问题。 阅读详情

1.变量,引用和对象

变量无类型,它的作用仅仅在某个时候引用了特定的对象而已,具体在内存中就是一个指针,仅仅拥有指向对象的空间大小。

变量和对象的关系在于引用,变量引用对象后,也就对应了赋值的过程。

在 python 中一切皆为对象,具体在内存中表示一块内存空间,每一个对象都会具有 identity,type 和 value 这三个内容。

Identity, 一旦对象被创建后,Identity 的值便不会发生改变。在 Cpython 中,其值体现为内存中保存对象的地址。is 操作符,比较对象是否相等就是通过这个值。通过 id() 函数查看它的整数形式。

Type, 和 Identity 一样,在对象创建后,Type 也不会发生变化。它主要定义了一些可能支持的值和操作(如对列表来说,会有求长度的操作)。通过 type() 函数可以得到对象的类型。

Value,用于表示的某些对象的值。当对象在创建后值可以改变称为 mutable,否则的话被称为 immutable.

举个例子,比如在 C 中,int x = 4 在内存中,是先分配了一个 int 类型的内存空间,然后把 4 放进空间内。

而 Python 中,x = 4 正好相反,是为 4 分配了一块的内存空间,然后用 x 指向它。由于变量可以指向各种类型的对象,因此不需要像 C 一样声明变量。这也就是 Python 被称为动态类型的意义。

并且在 Python 中,变量可以删除,但对象是无法删除的。

2.immutable 和 mutable 对象

immutable 对象拥有一个固定的值,包括 numbers, strings, tuples. 一个新的值被保存时,一个新的对象就会被创建。这些对象在作为常量的 hash 值中有着非常重要的作用,如作为字典的 key 时。

mutable 对象可以改变自身的值,但 id() 并不会发生改变。

当一些对象包含对其他对象的一些引用时,我们称这些对象为 containers, 例如 list, tuple, dictionary 这些都是 containers. 这里需要注意的是,一个 immutable containers 可以包含对 mutable 对象的引用(如在 tuple 中包含一个 list)。 但这个对象仍然称为 immutable 对象,因为 Identity 是不变的。

3.hashable 对象

当一个对象在生命周期内(实现了__hash__()方法)hash 值不会发生改变,并可以与其他对象进行比较(实现了 __eq__() 方法),称之为hashable 对象。

在 Python 内置的 immutable 对象 大多数都是 hashable 对象。immutable containers(tuples, frozenset)在引用的对象都是 hashable 对象时,才是hashable 对象。mutable containers 容器都不是 hashable 对象。用户自定义的类都是 hashable 对象,

4.浅拷贝与深拷贝

在介绍对象的拷贝前,先介绍一下 Python 中的赋值操作,可以让我们更好的了解拷贝的过程。

赋值操作

赋值操作的右边是简单表达式:

def normal_operation():

    # immutable objects
    # int
    a = 10
    b = 10
    print('----- int')
    print("id of a:{} , id of b: {}".format(id(a), id(b)))
    # id of a:1777364320 , id of b: 1777364320
    print(a == b)  # True
    print(a is b)  # True
    # str
    str_a = '123'
    str_b = '123'
    print('----- str')
    print("id of a:{} , id of b: {}".format(id(str_a), id(str_b)))
    # id of a:1615046978224 , id of b: 1615046978224
    print(str_a == str_b)  # True
    print(str_a is str_b)  # True

    # tuple
    tuple_a = (1, 2, 3)
    tuple_b = (1, 2, 3)
    print('----- tuple')
    print("id of a:{} , id of b: {}".format(id(tuple_a), id(tuple_b)))
    # id of a:1615047009696 , id of b: 1615047024856
    print(tuple_a == tuple_b)  # True
    print(tuple_a is tuple_b)  # False

    # mutable
    # set
    set_a = {1, 2, 3}
    set_b = {1, 2, 3}
    print('----- set')
    print("id of a:{} , id of b: {}".format(id(set_a), id(set_b)))
    # id of a:1615045625000 , id of b: 1615047012872
    print(set_a == set_b)  # True
    print(set_a is set_b)  # False

    # list
    list_a = [1, 2, 3]
    list_b = [1, 2, 3]
    print('----- list')
    print("id of a:{} , id of b: {}".format(id(list_a), id(list_b)))
    # id of a:1615047017800 , id of b: 1615045537352
    print(list_a == list_b)  # True
    print(list_a is list_b)  # False

    # dict
    dict_a = {"name": "xxx", "age": "123"}
    dict_b = {"name": "xxx", "age": "123"}
    print('----- dict')
    print("id of a:{} , id of b: {}".format(id(dict_a), id(dict_b)))
    # id of a:1615045521696 , id of b: 1615045522128
    print(dict_a == dict_b)  # True
    print(dict_a is dict_b)  # False

在 Cpython 中,id() 反映了对象在内存中的地址。可以看到,对于 immutable 对象中的 number 和 string 来说,CPython 本身对其做了一定的优化,在创建相同的内容时,使其 指向了相同的内存地址,从而被复用。

但是,Python 不会对所有 mutable 对象执行此操作,因为实现此功能需要一定的运行时成本。对于在内存中的对象来说,必须首先在内存中搜索对象(搜索意味着时间)。对于 number 和 string 来说,搜索到它们很容易,所以才对其做了这样的优化。

对于其他类型的对象,虽然创建的内容相同,但都在内存中完全创建了一块新的区域。

赋值操作的右边是 Python 中已存在的变量:

def assignment_operation():
    # immutable objects
    # int
    a = 10
    b = a
    print('----- int')
    print("id of a:{} , id of b: {}".format(id(a), id(b)))
    # id of a:1777364320 , id of b: 1777364320
    print(a == b)  # True
    print(a is b)  # True
    # str
    str_a = '123'
    str_b = str_a
    print('----- str')
    print("id of a:{} , id of b: {}".format(id(str_a), id(str_b)))
    # id of a:2676110142128 , id of b: 2676110142128
    print(str_a == str_b)  # True
    print(str_a is str_b)  # True

    # tuple
    tuple_a = (1, 2, 3)
    tuple_b = tuple_a
    print('----- tuple')
    print("id of a:{} , id of b: {}".format(id(tuple_a), id(tuple_b)))
    # id of a:2676110191640 , id of b: 2676110191640
    print(tuple_a == tuple_b)  # True
    print(tuple_a is tuple_b)  # True

    # mutable
    # set
    set_a = {1, 2, 3}
    set_b = set_a
    print('----- set')
    print("id of a:{} , id of b: {}".format(id(set_a), id(set_b)))
    # id of a:2676108788904 , id of b: 2676108788904
    print(set_a == set_b)  # True
    print(set_a is set_b)  # True

    # list
    list_a = [1, 2, 3]
    list_b = list_a
    print('----- list')
    print("id of a:{} , id of b: {}".format(id(list_a), id(list_b)))
    # id of a:2676110181704 , id of b: 2676110181704
    print(list_a == list_b)  # True
    print(list_a is list_b)  # True

    # dict
    dict_a = {"name": "xxx", "age": "123"}
    dict_b = dict_a
    print('----- dict')
    print("id of a:{} , id of b: {}".format(id(dict_a), id(dict_b)))
    # id of a:2676079063328 , id of b: 2676079063328
    print(dict_a == dict_b)  # True
    print(dict_a is dict_b)  # True

而当赋值操作的右边是已经存在的 Python 对象时,不论是什么类型的对象,都没有在内存中创建新的内容,仅仅是声明了一个新的变量指向之前内存中已经创建的对象,就像提供了一个别名一样。

dict_a = {‘1’:1}
dict_b = dict_a
print(“id of a:{} , id of b: {}”.format(id(dict_a), id(dict_b)))
id of a:140355639151936 , id of b: 140355639151936

dict_b = {}
print(“id of a:{} , id of b: {}”.format(id(dict_a), id(dict_b)))
id of a:140355639151936 , id of b: 140355639922176

由于 dict_b = dict_a操作,让两个变量同时指向了同一块内存区域。自然 id 相等。
当对 dict_b 重新赋值时,仅让 b 指向了另外一块内存区域,并不会影响 a 的指向,由于两块内存区域不同,自然id 并不想等。
改变赋值后的对象

def assignment_operation_change():
    # immutable objects
    # int
    a = 10
    print("id of a:{}".format(id(a)))  
    # id of a:1994633728
    b = a 
    a = a + 10
    print('----- int')
    print("id of a:{} , id of b: {}".format(id(a), id(b)))
    # id of a:1994634048 , id of b: 1994633728
    print(a == b)  # False
    print(a is b)  # False

    # mutable objects
    # list
    list_a = [1, 2, 3]
    list_b = list_a
    list_a.append(4)
    print('----- list')
    print("id of a:{} , id of b: {}".format(id(list_a), id(list_b)))
    # id of a:2676110181704 , id of b: 2676110181704
    print(list_a == list_b)  # True
    print(list_a is list_b)  # True

当修改 imutable 对象时,由于其本身不可改变,只能在内存中新申请一块新的空间,用于存储修改后的内容。对应上面 a=20 的操作,这时再判断 a 和 b 时,由于指向了内存的不同位置,所以 a,b不在相等。a 原来指向的内存区域不会被回收,因为现在由 b 指向。可以看到 b 指向的内存地址和 a 之前的指向的内存地址是一致的。

当修改 mutable 对象时,由于都指向相同的内存地址,所以对变量 list_a 修改的操作,也会映射到变量 list_b。

总结一下:

  • 指向 imutable 的不同变量,当其中一个变量被修改时,其他变量不受影响,因为被修改后的变量会指向一个新创建的对象。

  • 指向 mutable 对象的不同变量,当其中一个变量修改这个对象时,会影响到指向这个对象的所有变量。

浅拷贝

浅拷贝创建了一个对象,这个对象包含了对被拷贝元素的参考。 所以当使用浅拷贝来复制 conainters 对象时,仅仅拷贝了那些嵌套元素的引用。

def shallow_copy():
    # immutable objects
    # int
    a = 10
    b = copy(a)
    print('----- int')
    print("id of a:{} , id of b: {}".format(id(a), id(b)))
    # id of a:1777364320 , id of b: 1777364320
    print(a == b)  # True
    print(a is b)  # True
    # str
    str_a = '123'
    str_b = copy(str_a)
    print('----- str')
    print("id of a:{} , id of b: {}".format(id(str_a), id(str_b)))
    # id of a:2676110142128 , id of b: 2676110142128
    print(str_a == str_b)  # True
    print(str_a is str_b)  # True

    # tuple
    tuple_a = (1, 2, 3)
    # Three methods of shallow copy
    # tuple_b = tuple_a[:]
    # tuple_b = tuple(tuple_a)
    tuple_b = copy(tuple_a)
    print(id(tuple_b))
    print('----- tuple')
    print("id of a:{} , id of b: {}".format(id(tuple_a), id(tuple_b)))
    # id of a:2676110191640 , id of b: 2676110191640
    print(tuple_a == tuple_b)  # True
    print(tuple_a is tuple_b)  # True

    # mutable
    # set
    set_a = {1, 2, 3}
    # Two methods of shallow copy
    # set_b = set(set_a)
    set_b = copy(set_a)
    print('----- set')
    print("id of a:{} , id of b: {}".format(id(set_a), id(set_b)))
    # id of a:2099885540520 , id of b: 2099888490984
    print(set_a == set_b)  # True
    print(set_a is set_b)  # False

    # list
    list_a = [1, 2, 3]
    # Three methods of shallow copy
    # list_b = list_a[:]
    # list_b = list(list_b)
    list_b = copy(list_a)
    print('----- list')
    print("id of a:{} , id of b: {}".format(id(list_a), id(list_b)))
    # id of a:2099888478280 , id of b: 2099888478472
    print(list_a == list_b)  # True
    print(list_a is list_b)  # False

    # dict
    dict_a = {"name": "xxx", "age": "123"}
    # Two methods of shallow copy
    # dict_b = dict(dict_a)
    dict_b = copy(dict_a)
    print('----- dict')
    print("id of a:{} , id of b: {}".format(id(dict_a), id(dict_b)))
    # id of a:2099855880480 , id of b: 2099886881024
    print(dict_a == dict_b)  # True
    print(dict_a is dict_b)  # False

这里有一点需要注意,对于 string 和 number 来说,正如上面提到的 Cpython 做了相应的优化,让不同的变量指向了相同的内存地址,进而 id 的值是相等的。

但对于元组这个 immutable 元素来说,执行 浅拷贝时,也不会创建一个内存区域,只是返回一个老元组的引用。

对于其他的 mutable 对象,在浅拷贝后都会创建一个新的内存区域,包含了被拷贝元素的引用。

浅拷贝正如它的名字那样,当拷贝嵌套的 mutable 元素时,就会出现问题:

def shallow_copy_change_value():
    # list
    # Python小白学习交流群:711312441
    list_a = [1, 2, 3, [4, 5, 6]]
    list_b = copy(list_a)
    list_a[0] = 10
    list_a[3].append(7)
    print('----- list')
    print("ia:{} ,b: {}".format(list_a, list_b))
    print("id of a:{} , id of b: {}".format(id(list_a), id(list_b)))
    # a:[10, 2, 3, [4, 5, 6, 7]] ,b: [1, 2, 3, [4, 5, 6, 7]]
    # id of a:1698595158472 , id of b: 1698595159752
    print(list_a == list_b)  # False
    print(list_a is list_b)  # False

下面是对上面 list 浅拷贝的图解:

执行浅拷贝操作:

在这里插入图片描述
在 list_b 执行浅拷贝后,创建一个新的对象,新对象中的 list_a[0] 指向 1.

修改 list_a 操作:
在这里插入图片描述
当执行 list_a[0] = 10 操作时,由于 list_a[0] 本身是 number 类型,会重新创建一块区域,用于保存新的值 10. 而新创建的 list_b[0] 并不会受到影响,还会指向之前的内存区域。

当修改list_a[3] 操作时,由于list_a[3] 在浅拷贝后,新创建的对象中不会 嵌套创建 一个新的 list_a[3] 对象,仅仅是指向了之前的 list_a[3] 对象。所以当修改 list_a[3] 时, list_b[3] 也会收到影响。

深拷贝

对于深拷贝操作来说,除了会创建一个新的对象外,会还递归的遍历老对象的中的嵌套元素,并形成新的副本。

def shallow_deepcopy_change_value():
    # list
    list_a = [1, 2, 3, [4, 5, 6]]
    list_b = deepcopy(list_a)
    list_a[0] = 10
    list_a[3].append(7)
    print('----- list')
    print("a:{} ,b: {}".format(list_a, list_b))
    print("id of a:{} , id of b: {}".format(id(list_a), id(list_b)))
    # id of a:2099888478280 , id of b: 2099888478472
    print(list_a == list_b)  # False
    print(list_a is list_b)  # False

下面是对应图解过程:

执行深拷贝操作:
在这里插入图片描述
修改 list_a 操作:
在这里插入图片描述
这里 list_a 和 list_b 已经是完全的不同的两个对象。

总结

在这篇文章中,主要介绍了 Python 中对象,以及对象的拷贝过程,主要有下面几个重要的内容:

  • Python 中变量没有类型,仅仅可看做一个指针,通过引用指向对象。变量可以删除,但对象不行。

  • Python 对象被创建后,会拥有 identity,type 和 value 三个属性。

  • immutable 和 mutable,主要在于 value 在其生命周期内是否能发生变化。

  • 修改 mutable 对象时,所有指向它的变量都会受到影响。修改 immutable 对象时,指向它的其他变量没有影响。

  • immutable 的大多数对象都是 hashable,但要考虑 immutable containers 的特殊情况。

  • 浅拷贝会创建一个新的内存区域(对象),但其内部是对原对象内部引用的拷贝,在使用 mutable 对象时,存在一定的风险。

  • 深拷贝不但会创建一个新的内存区域(对象),还会递归的创建原对象的所有嵌套对象,但也带来了一些效率的问题。

Python学习:Python对象的比较、拷贝 我们在写python代码时,经常用到 Python 对象比较和复制的语句,但语句背后发生了什么,总是不清楚。 举一些我们用到的例子: 判断a和b是否相等的例子: if a == b: ... 两个列表之间的拷贝,l2 就是 l1 的拷贝。 l1 = [1, 2, 3] l2 = list(l1) 其中a == b是比较两个对象的值相等,还是两个对象完全相等呢? l2 是 l1 的浅拷贝(shallow copy)还是深度拷贝(deep copy)呢? 一、比较’==’ VS ‘is’ 等于() 阅读详情

相关推荐

python对象的引用&拷贝机制

python的引用、拷贝机制需要有一个明确的认知,这样才能保证在较大项目中不会因为引用导致误改而找不到原因

GentleCP的博客 989

Python 对象拷贝的详细教程

在这篇文章中,主要介绍了 Python 中对象,以及对象的拷贝过程,主要有下面几个重要的内容:Python 中变量没有类型,仅仅可看做一个指针,通过引用指向对象。变量可以删除,但对象不行。Python 对象被创建后,会拥有 identity,type 和 value 三个属性。immutable 和 mutable,主要在于 value 在其生命周期内是否能发生变化。修改 mutable 对象时,所有指向它的变量都会受到影响。修改 immutable 对象时,指向它的其他变量没有影响。

Python热爱者的博客 675

python:对象复制

1、Python中一切皆对象 ⑴在Python中,无论是定义的数值、字符串、列表、元组、集合、字典还是函数、类等都看作是一种对象 ⑵列表、元组、集合、字典属于复合对象,它们可以包含数值、字符串,也可以互相嵌套 ⑶对象都是可以赋值给变量的2、列表、字典、集合为可变对象,这些对象的有些方法是在对象本身上操作的 ⑴直接在对象本身上进行修改:改变的是对象本身,而不是生成一个修改后的新对象 ⑵如append()、remove()方法等等。这类方法都是在对象本身上进行修改,返回值

不怕猫的耗子A 6728

python对象拷贝

在 Python 中,对象的拷贝方式主要有三种:浅拷贝(shallow copy)、深拷贝(deep copy)、以及直接赋值。每种方式的行为有所不同,特别是在处理嵌套对象时。

qq_27390023的博客 564

【Python 语法】Python 一切皆对象,可变和不可变对象,浅拷贝和深拷贝

python 浅拷贝和深拷贝

一杯水果茶!足矣~ 1687

drm 之modes

#define _GNU_SOURCE #include <errno.h> #include <fcntl.h> #include <stdbool.h> #include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/mman.h> #include <time.h&...

u012794472的专栏 3716

python引用、浅拷贝、深拷贝

在python中,对象的赋值往往是通过“=”进行的。但是由于“=”右边的类型方式不一样,所以产生变量虽然值相同,但是在内存中的地址值不同,可能会造成内存空间的浪费。如题所示,对象赋值中存在三种类型情况的赋值 引用赋值 引用赋值l2=l1 ,首先创建个变量l2,然后在创建一条引用,把这条引用指向l1的地址值。然后l1和l2共同使用这一块地址值。 当l1进行变化后,l2也跟着变化 l1=...

weixin_43979988的博客 631

Python爬虫案例:从39问医生网爬取口腔科的在线问答记录(单轮问答)

本次实验爬取39问医生网中口腔科分类下的所有在线单轮问答记录,每页32条,共100页,总数据量为3200条,最终结果以excel格式保存。

JieBao11的博客 1640

【python】对象的拷贝:浅拷贝和深拷贝

浅拷贝只复制对象的顶层元素,如果对象中的元素是可变类型(如列表),则只复制这些子对象的引用地址,而不是引用的对象本身。浅拷贝中的元素,是原对象中子对象的引用,因此,如果原对象中的元素是可变的,改变其也会影响拷贝后的对象,存在一定的副作用。深度拷贝则会递归地拷贝原对象中的每一个子对象,生成一个全新的、完全独立的对象,因此拷贝后的对象和原对象互不相关。另外,深度拷贝中会维护一个字典,记录已经拷贝的对象及其ID,来提高效率并防止无限递归的发生。

MAOZI8的博客 1224

删除win10电脑U盘使用记录

手工删除:和查看的方法类似,分三步,缺一不可,顺序也不能反! 第一步 设置环境变量,变量名为“devmgr_show_nonpresent_devices”,值为“1”。 第二步 打开设备管理器,勾上“查看”菜单中的“显示隐藏设备”。如果之前已经打开设备管理器,则要关了,重新打开。 第三步 清除“磁盘驱动器”、“存储卷”、“通用串行总线控制器”3个栏目下所有的灰色的图标,注意是所有!右键点击灰色图标,然后选择“卸载”。 成功 :结果USBSTOR 没有了 ...

qq_40544338的博客 2万+

NVMe-MI --- Message Servicing Model(消息服务模型)

本文主要介绍NVMe-MI消息服务模型,两个主要类别是请求消息和响应消息。并介绍带外机制消息服务状态机。

智小星的博客 2009

python如何拷贝一个对象_python里面如何拷贝一个对象

Python中的对象之间赋值时是按引用传递的,如果需要拷贝对象,需要使用标准库中的copy模块1.copy.copy浅拷贝只拷贝父对象,不会拷贝对象的内部的子对象。2.copy.deepcopy深拷贝拷贝对象及其子对象一、http://blog.youkuaiyun.com/sharkw/article/details/1934090需求:你想复制一个对象.因为在Python中,无论你把对象做为参数...

weixin_39525617的博客 1388

【keras】走近VGG16卷积神经网络

        VGG16是一个16层的卷积神经网络模型,输入数据的维度为224*224*3,即长宽均为224像素的RGB彩色图片,VGG16模型的权重由ImageNet训练而来。由于其具有简单实用的优点,因此,在图像分类和目标检测任务中得到了较为广泛的应用。 1.卷积神经网络的基本概念 1.1卷积         简单的将其理解为一种数学运算,具体的计算过程如下图所示:       ...

XYZ 1万+

Python里面如何拷贝一个对象?

So: Python中的对象之间赋值时是按引用传递的,如果需要拷贝对象,需要使用标准库中的 copy模块。 1. copy.copy 浅拷贝 只拷贝父对象,不会拷贝对象的内部的子对象。 2. copy.deepcopy 深拷贝 拷贝对象及其子对象 一、http://blog.youkuaiyun.com/sharkw/article/details/1934090 需求

u011860731的专栏 7627

Camunda 7.x 系列【22】全局监听器

Camunda支持义一个全局ExecutionListener和一个全局TaskListener,会捕获流程中发生的所有事件的通知,这样可以定义一个全局的审批人检查监听器,作用于所有用户任务。

记录知识、锤炼自我 2940

中国土地市场网爬取

实习期间老板需要对土地数据进行爬取,想来想去就Google到了.应该算是种类最齐全的土地数据了。Github地址:https://github.com/AnTi-anti/china_land/tree/master。

猫敷雪 5461

python中对象的赋值、浅拷贝和深拷贝

1. 赋值:简单的对象引用 在python中,变量赋值实际上是简单的对象引用。在创建一个对象后,再把它赋给另一个变量的时候,python并没有拷贝这个对象,而只是简单地拷贝了这个对象的引用。 (1)原子类型的赋值 &gt;&gt;&gt; x = 3.14 &gt;&gt;&gt; y = x &gt;&gt;&gt; x,y (3.14, 3.14) &gt;&gt;&gt; id...

Yvettre的博客 5234

华为OD机试真题 新系统 9月27号 【数据中心最佳维护窗口】

华为OD机试真题 新系统【数据中心最佳维护窗口】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试真题 【数据中心最佳维护窗口】多语言题解。

qq_45776114的博客 1150

Python对象的浅拷贝与深拷贝笔记

做一个对象的浅拷贝不会克隆子对象。因此,副本并不完全独立于原件。对象的深层副本将递归地克隆子对象。克隆完全独立于原始副本,但创建深度副本的速度较慢。您可以使用copy模块复制任意对象(包括自定义类)。

m0_65482549的博客 1113

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

15 | Python对象的比较、拷贝

今天这节课,我们一起学习了 Python 中对象的比较和拷贝,主要有下面几个重点内容。比较操作符'=='表示比较对象间的值是否相等,而'is'表示比较对象的标识是否相等,即它们是否指向同一个内存地址。比较操作符'is'效率优于'==',因为'is'操作符无法被重载,执行'is'操作只是简单的获取对象的 ID,并进行比较;而'=='操作符则会递归地遍历对象的所有值,并逐一比较。浅拷贝中的元素,是原对象中子对象的引用,因此,如果原对象中的元素是可变的,改变其也会影响拷贝后的对象,存在一定的副作用。

qq_37756660的博客 1038

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【Python】对象拷贝、对象传参、对象引用

 1. 如何实现对象的拷贝呢,python 有 copy模块。 用法: import copy 对象2 = copy.copy(对象1) 问题: 浅拷贝,改变一个对象,另外一个会跟着改变。 根据评论w6443同学提醒纠正此处:浅拷贝列表时,如果改变列表内不可变元素,列表会复制一份;但是改变列表内可变元素,如子列表,那么修改原列表后,浅拷贝列表也会自动改变。 解决: 对象2 = co...

小白兔的窝 9239

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

Python对象的赋值和拷贝

0 前言 前面讲了python的可变对象和不可变对象,总结起来就是,可变对象指向的内存中的值可以修改,不可变对象指向的内存的中的值不可以修改,如果想改变这个对象的值,会重新申请一个内存地址,修改值后存到新的地址上,然后另对象指向新的内存地址。关于可变对象和不可变对象的内容可以参考博客. 这篇我们来看一下对象的深浅拷贝,主要是针对可变对象,对于不可变对象,修改了对象的值,就会重新分配地址,对原来对象...

Lavi的专栏 1112

Python里面如何拷贝一个对象?(赋值,浅拷贝,深拷贝的区别)

本文主要来自:一文了解Python深拷贝与浅拷贝问题 拷贝的产生缘由: 在平时工作中,经常涉及到数据的传递,在数据传递使用过程中,可能会发生数据被修改的问题。为了防止数据被修改,就需要在传递一个副本,即使副本被修改,也不会影响原数据的使用。为了生成这个副本,就产生了拷贝。 背景知识: 在 Python 中,变量名就是地址的一种表示形式,并不开辟开辟存储空间。 可变对象:所谓可...

Todd_168的博客 1472

python如何拷贝一个对象_Python的对象拷贝

对象拷贝在面向对象编程中,复制一个现有对象的副本,被称为对象拷贝。生成的对象被称之为对象副本。拷贝是基本的操作,但是在实际操作过程中会有一些需要注意的地方。有多种方法来拷贝对象,最常见的是通过拷贝构造函数或者克隆函数。拷贝的主要目的是对副本做出修改、移动,或者是保留当前值。如果不需要实现以上目的,则创建对原始数据的引用是更加高效的选择。Python的对象拷贝在Python中,赋值语句总是建立对象的...

weixin_39686192的博客 358

python—类和对象之浅拷贝和深拷贝详细讲解

一、变量的赋值操作 定义:只是形成2个变量,实际上还是指向同一个对象 代码如下: 内存示意图: 将创建CPU类的实例对象赋值给cpu1进行储存,所以cpu1的id为0212, 然后将cpu1赋值给cpu2,cpu2的id也为0212; cpu1和cpu2指向同一个类的实例对象。 在一个类中,有一个类的实例对象,用2个变量去存储。 二、浅拷贝 定义:python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝,因此,源对象与拷贝对象会引用同一个子对象 代码: 代码执行结果为:可以看到compute

python全栈 6592

python中拷贝对象的区别

一、赋值、引用 在python中赋值语句总是建立对象的引用值,而不是复制对象。因此,python变量更像是指针,而不是数据存储区域 这点和大多数语音类似吧,比如C++、Java等 1、先看个例子: values=[0,1,2] values[1]=values print(values) # [0, [...], 2] 预想应该是:[0,[0,1...

diaoding3046的博客 1094
上一篇: Python中os.listdir和os.walk(获取路径方法)的区别
下一篇: Python中匿名函数lambda是什么
Python程序u猿
博客等级 码龄5年 622粉丝 84原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值