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计算IV值的示例讲解

    下面是关于“Python计算IV值的示例讲解”的完整攻略。 标题 什么是IV值 IV指隐私保护中常用的指标,即信息量。它既反应了数据的敏感程度,又反映了数据的稀缺性。通常情况下,IV值越大,预测目标变量的能力越高。 如何计算IV值 计算IV值的公式为:IV=∑(good%−bad%)×WOE,其中good表示好样本数,bad表示坏样本数,WOE表示分割后某一…

    python 2023年5月14日
    00
  • ROS1 rosbag的详细使用并且使用python合并bag包的方法

    下面是关于“ROS1 rosbag的详细使用并且使用python合并bag包的方法”的完整攻略: 什么是ROS1 rosbag ROS1 rosbag是ROS中一个非常强大的数据记录与回放工具,可以用来记录机器人传感器、控制指令、软件节点的输入输出等所有的ROS中的消息话题。记录下来的数据可以通过rosbag play命令进行回放,从而方便地对机器人的行为进…

    python 2023年6月2日
    00
  • Python实现命令行通讯录实例教程

    下面是“Python实现命令行通讯录实例教程”的完整攻略。 1. 程序说明 本程序是利用 Python 实现的命令行通讯录,可以添加,删除,查询和修改联系人信息。 2. 程序实现 2.1 安装依赖 在开始编写程序之前需要先安装相应依赖,使用以下命令可以一次性安装所需的所有依赖: pip install Click PrettyTable 其中,Click 是…

    python 2023年6月2日
    00
  • python 实现A*算法的示例代码

    Python实现A*算法的示例代码 A算法是一种常用的启发式搜索算法,它可以用于寻找最短路径。在Python中,可以使用heapq和queue库实现A算。本文将详细讲解Python实现A*算法的整个攻略,包括算法原理、Python实现过程和示例。 算法原理 A*算法的基本思想是根据启函数,搜索最短路径。具体实现过程如下: 初始化一个起点和终点。 使用启发函数…

    python 2023年5月14日
    00
  • Python列表append()函数使用方法详解

    以下是“Python列表append()函数使用方法详解”的完整攻略。 1. append()函数概述 在Python中,列表是一种基本数据结构,用于储一组有序的元素。列表中的元素可以是任意类型的数据,括数字、字符串、列表等。append()函数是Python列表的一个常用函数,用于向列表末尾添加一个元素。 append()函数的语法如下: list.app…

    python 2023年5月13日
    00
  • 如何通过匹配Python中不同长度的字典中的值来替换列值?

    【问题标题】:How to replace column values by matching values in a dictionary of a different length in Python?如何通过匹配Python中不同长度的字典中的值来替换列值? 【发布时间】:2023-04-06 15:08:02 【问题描述】: 我有一个看起来像这样的数…

    Python开发 2023年4月7日
    00
  • 关于Python的一些学习总结

    以下是关于 Python 学习总结的完整攻略: 问题描述 Python 是一种高级编程语言,具有简单易学、可读性强、功能强大等特点。本文将介绍 Python 的一些学习总结,包括基础语法、常用模块、面向对象编程等方面。 解决方法 1. 基础语法 1.1 变量 在 Python 中,变量是用来存储数据的容器。可以使用 = 运算符将数据赋值给变量。示例代码如下:…

    python 2023年5月13日
    00
  • python 字符串详解

    Python 字符串详解 字符串是Python中最常用的数据类型之一。在本文中,我们将共同探讨Python中字符串的基本概念、常见操作以及字符串格式化等方面。 字符串的定义 Python字符串是用一对引号(单引号或双引号)括起来的文本数据,例如: str1 = ‘This is a string.’ str2 = "这是一个字符串。" 另…

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