Python中的可变对象与不可变对象

Python中所有类型的值都是对象,这些对象分为可变对象与不可变对象两种:

  • 不可变类型

    floatintstrtupleboolfrozensetbytes

    tuple自身不可变,但可能包含可变元素,如:([3, 4, 5], 'tuple')

  • 可变类型

    listdictsetbytearray自定义类型

 

+=操作符

+=操作符对应__iadd__魔法方法,对于不可变对象a+=ba=a+b等价,对于可变对象并不等价,dictset不支持+=和+操作符。

l1 = l2 = [1, 2, 3]
# 只有l1发生变化
# l1 = l1 + [4]
# l1和l2都发生变化,输出[1, 2, 3, 4, 5]
l1 += [4, 5]
print(l1)
print(l2)

 

浅拷贝 深拷贝

与赋值不同,拷贝(可能)会产生新的对象,可通过拷贝来避免不同对象间的相互影响。

在Python中,不可变对象,浅拷贝和深拷贝结果一样,都返回原对象:

import copy
​
​
t1 = (1, 2, 3)
t2 = copy.copy(t1)
t3 = copy.deepcopy(t1)
print(t1 is t2) # True
print(t1 is t3) # True
print(id(t1), id(t2), id(t3)) # 输出相同值

对于可变对象,则会产生新对象,只是若原对象中存在可变属性/字段,则浅拷贝产生的对象的属性/字段引用原对象的属性/字段,深拷贝产生的对象和原对象则完全独立:

l1 = [1, 2, 3]
l2 = l1.copy()
print(l1 is l2)  # False
l2[0] = 100
print(l1[0])  # 1

 

import copy
​
​
class Id:
    def __init__(self, name):
        self.name = name
​
​
class Person:
    def __init__(self, id: Id):
        self.id = id
​
​
p1 = Person(Id("eason"))
p2 = copy.copy(p1)
print(p1 is p2)  # False
print(p1.id is p2.id)  # True
p2.id.name = "p2"
print(p1.id.name)  # p2
​
p3 = copy.deepcopy(p1)
print(p1 is p3)  # False
print(p1.id is p3.id)  # False
print(p1.id.name is p3.id.name)  # True,字符串不可变,这里name属性的地址一样
p3.id.name = "p3"
print(p1.id.name)  # 还是p2

 

Python中可使用以下几种方式进行浅拷贝:

  • 使用copy模块的copy方法

  • 可变类型切片

    l1 = [1, 2, 3]
    l2 = l1[:]
    print(l1 is l2)  # False

     

  • 可变类型的copy方法

    [].copy()
    {}.copy()
    set().copy()

     

  • 调用list, set, dict方法

    l1 = [1, 2, 3]
    l2 = list(l1)
    l2[0] = 100
    print(l1[0])  # 1

     

  • 推导式

    列表、字典、集合推导式

    class Person:
        def __init__(self, name):
            self.name = name
    ​
    ​
    l1 = [Person("l1")]
    l2 = [i for i in l1]
    print(l1 is l2)  # False
    print(l1[0] is l2[0])  # True
    ​
    s1 = {Person("s1")}
    s2 = {i for i in s1}
    print(s1 is s2)  # False
    ​
    ele1 = s1.pop()
    ele2 = s2.pop()
    print(ele1 is ele2)  # True

     

推荐阅读

Different behaviour for list.__iadd__ and list.__add__

学习Python一年,这次终于弄懂了浅拷贝和深拷贝

copy — Shallow and deep copy operations

原文链接:https://www.cnblogs.com/Cwj-XFH/p/17308499.html

本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python中的可变对象与不可变对象 - Python技术站

(0)
上一篇 2023年4月17日
下一篇 2023年4月17日

相关文章

  • 暂停/恢复嵌入式 python 解释器

    【问题标题】:Pause/Resume embedded python interpreter暂停/恢复嵌入式 python 解释器 【发布时间】:2023-04-05 21:56:01 【问题描述】: 是否有可能在我需要的地方暂停/恢复嵌入式 python 解释器的工作?例如: C++伪代码部分: main() { script = “python_scr…

    Python开发 2023年4月6日
    00
  • Python爬虫实例扒取2345天气预报

    下面是Python爬虫实例扒取2345天气预报的完整攻略: 1. 准备工作 在开始实现爬虫之前,需要安装Python环境和必要的爬虫库。接下来是具体的准备工作: 1.1 安装Python环境 Python的安装非常简单,可以到Python官网上下载安装包,根据图形化安装界面进行安装。 1.2 安装必要的Python库 本次爬虫我们需要使用以下几个Python…

    python 2023年5月19日
    00
  • python实现录音小程序

    下面我将为你详细讲解“python实现录音小程序”的完整攻略,过程中包含以下几个步骤: 安装PyAudio和wave库 录音 保存录音文件 示例说明 1. 安装PyAudio和wave库 要实现录音功能,我们需要使用到PyAudio和wave库。在终端中输入以下命令来安装: pip install pyaudio wave 2. 录音 在Python中实现录…

    python 2023年5月23日
    00
  • 如何使用Python进行音频处理?

    使用Python进行音频处理的方法有很多,下面我将介绍其中比较常用的一些方法。 1. 安装必要的库 要使用Python进行音频处理,首先需要安装一些必要的库,例如: numpy:用于处理音频数据 scipy:用于科学计算、信号处理等 librosa:用于音频处理、特征提取等 matplotlib:用于数据可视化 你可以在终端中使用以下命令来安装这些库: pi…

    python 2023年4月19日
    00
  • python重试装饰器示例

    Python重试装饰器是一种常见的用于解决网络请求、接口调用等场景下出现错误或异常的情况。其主要工作是将函数重复执行直到成功或达到重试次数限制。下面我们将从以下几个方面详细讲解Python重试装饰器的使用攻略。 1. 装饰器原理及概念 装饰器(decorator)是Python语言中的一种特殊语法元素,用于在源代码中动态地修改函数或类定义的代码。简单来说,装…

    python 2023年5月13日
    00
  • Python中遍历列表的方法总结

    Python中遍历列表的方法总结 在Python中,列表是一种常见的数据类型,它可以包含任意类型的数据,包括数字、字符串、元组、列表、字典等。在处理列表时,遍历列表是一种常见的操作。本攻略将介绍Python中遍历列表的方法,并提供多个示例说明。 方法一:使用for循环遍历列表 使用for循环遍历列表是Python中最常用的方法之一。以下是一个示例代码,演示如…

    python 2023年5月13日
    00
  • python调用shell的方法

    Python 作为一种高级语言,已经被广泛应用于各种领域和场合下。但是在某些情况下,Python需要调用一些比较底层的操作系统命令,例如Shell命令。在这种情况下,Python 可以通过内置 subprocess 模块来调用 Shell 命令。 调用外部命令的两种方式 使用 Python 中的 subprocess 模块,在 Python 中执行 Shel…

    python 2023年6月2日
    00
  • python 递归深度优先搜索与广度优先搜索算法模拟实现

    下面是详细讲解“Python递归深度优先搜索与广度优先搜索算法模拟实现”的完整攻略,包括算法原理、Python实现和两个示例。 算法原理 深度优先搜索(DFS)和广度优先搜索(BFS)是两种常用的图搜索算法。DFS是一种递归算法,其主要思想是从起点开始,沿着一条路径一走到底,直到无法继续为止,然后回溯到上一个节点,继续搜索下一条路径。BFS是一种迭代法,其主…

    python 2023年5月14日
    00
合作推广
合作推广
分享本页
返回顶部