Python以其灵活性而闻名,提供了丰富的数据类型,这些数据类型大致可以分为可变类型和不可变类型。作为一名好奇的Python开发者,可能也会好奇这些概念是如何影响数据的。数据在内存中是如何被处理和操作的?它们又是如何影响程序质量的?本文将为提供一个全面的概览,探讨Python中可变与不可变对象的重要性,以及它们在不同Python对象中的工作方式,比如基本数据类型(如整数、浮点数、字符串等)和内置数据类型(如列表、字典、集合、元组等)。
从高层次来看,可变性指的是任何对象在创建后能否被修改、改变或更新。这意味着如果一个对象是可变的,可以在不创建新对象的情况下改变其状态或内容。另一方面,不可变性意味着一旦对象被创建,其状态就不能被改变/修改/更新。对这些对象的任何改变都会创建一个新的对象,并分配不同的内存,而不是改变现有的对象。
下图展示了Python丰富的数据类型可以被分为两类:可变对象和不可变对象,它们进一步被细分。
让来看一下所有内置数据类型的比较:
数据类型 | 可变/不可变 | 描述 | 用例 |
---|---|---|---|
整数 | 不可变 | 整数(例如,1,-5,42)。 | 用于处理不变化的数值数据。 |
浮点数 | 不可变 | 带有小数点的数字(例如,3.14,-0.001)。 | 适用于科学计算、财务数据等。 |
布尔值 | 不可变 | 逻辑值:True或False。 | 条件检查,逻辑运算。 |
字符串 | 不可变 | 字符序列(例如,“hello”,“world”)。 | 用于文本操作、文档处理等。 |
元组 | 不可变 | 有序的项目集合(例如,(1, 2, 3))。 | 适用于常量数据,可以用作字典键。 |
冻结集合 | 不可变 | 无序的唯一项目集合,集合的不可变版本。 | 用于需要保持常量和可哈希的集合的情况。 |
复数 | 不可变 | 带有实部和虚部的数字(例如,1 + 2j)。 | 用于科学计算、信号处理等。 |
列表 | 可变 | 有序的项目集合(例如,[1, 2, 3])。 | 当需要频繁修改、添加或删除元素时使用。 |
字典 | 可变 | 键值对集合(例如,{"name": "John", "age": 30})。 | 适用于映射关系、查找和数据存储。 |
集合 | 可变 | 无序的唯一项目集合(例如,{1, 2, 3})。 | 最适合用于成员测试、去除重复项等。 |
自定义对象(类) | 可变/不可变 | 行为取决于类如何定义(默认为可变)。 | 根据需求定制行为;可以控制可变性。 |
为了更Pythonic地理解这些概念,可以查看以下文章:
在这些文章中,讨论了这些数据类型的可变性和不可变性、`id`函数、浅拷贝和深拷贝等,以及代码。注意:不过,建议在阅读本文后再查看这些代码。本文增强了对“内存空间内部发生了什么?”的理解。
当讨论不可变性在内存层面时,不可变对象不能被直接修改。任何看似修改不可变对象的操作都会在内存中创建一个带有修改值的新对象。可变对象共享之前分配的内存。这些对象的变化发生在原地,修改现有内存内容,而不需要新的分配。
在进一步探讨之前,先来理解关于从内存中删除对象的两个最常见概念。
Python的内存管理依赖于两件事情:引用计数和垃圾收集器,来处理对象的删除。让一一了解它们:
Python跟踪指向每个对象的引用数量。这被称为引用计数。