可变对象和不可变对象 Python

⚡ 智能摘要

可变对象和不可变对象 Python 可变类型和不可变类型的区别在于它们在创建后状态是否会改变。像列表和字典这样的可变类型会原地改变状态,而像字符串和元组这样的不可变类型则不能。

  • 🔘 定义: 可变对象可以就地更改其值,而不可变对象一旦创建就不能更改。
  • ☑️ 可变类型: 列表、字典和集合可以在创建后进行修改,而无需创建新对象。
  • 不可变类型: 整数、浮点数、布尔值、字符串、元组和冻结集一旦初始化,就会保持固定的值。
  • ???? 字典键: 只有不可变的、可哈希的对象才能用作键,这样才能保证查找的可靠性。
  • 🤖 人工智能相关性: 机器学习中的数组和张量都是可变的,因此 trac原地编辑可以保护可复现性。

可变和不可变 Python

什么是可变对象?

可变的 Python 可以定义为可以改变的对象或被视为本质上可变的东西。可变意味着修改或编辑值的能力。

中的可变对象 Python 使程序员能够拥有可以改变其值的对象。它们通常用于存储数据集合。它可以被视为已经变异的东西,并且对象内适用的内部状态已经改变。

什么是不可变对象?

不可变对象 Python 可以将其定义为值和属性不会随时间改变的对象。这些对象一旦创建和初始化就成为永久性的,它们是数据结构的重要组成部分。 Python.

Python 用于数字, 元组、字符串、冻结集和用户定义类(但有一些例外)。它们无法改变,并且一旦初始化,它们的值和内容将保持不变,因此称为不可变的。

In Python,一切都是对象

在 Python 编程语言中,所有事物都可以看作是对象,包括列表、整数和函数。这个特性可以与其他支持对象的编程语言进行比较。

可以使用以下方法验证此功能 Python 解释器如下所示:-

Python 码:

print("The following instance is an object:",isinstance(3,object))
print("Another instance for object", isinstance(True, object))
def my_func():
    return "guru99"
print("This is a function example and regarded as an object in Python:", isinstance(my_func, object))

输出:

A following instance is an object: True
Another instance for object True
This is a function example and regarded as an object in Python: True

另外, Python 提供了一个名为 id 的内置函数,它返回对象在内存中的地址 Python 编程语言。

Python 码:

z=200
id(z)
print("The id of object is", id(z))

输出:

the id of object is 9795360

在上面的代码中,id 函数的语法为 id(obj),它给出了 obj 的地址 Python 内存。这里有一个名为 z 的对象,它被赋值为 200。然后对象 z 被传递到 id 函数作为 id(z),并且 Python 将对象地址传递为 9795360。

中的可变对象 Python

在可变对象中,对象的值会在一段时间内发生变化。

在这个例子中,我们解释了可变对象 Python,它利用列表作为可变对象的应用,如下所示:-

Python Code:

mut_list = [1, 2, 3]
  print("The list in Python",mut_list)
mut_list[0] = 'Gurru99'
mut_list
  print("The list in Python after changing value",mut_list)

输出:

The list in Python [1, 2, 3]
The list in Python after changing value ['Gurru99', 2, 3]

正如我们在上面的例子中所看到的,可变列表中 Python 原元素的值为 1、2、3。可变列表的第一个元素从 1 变为 2。 Guru99,并且在初始化新值时不会创建新对象。

这里我们可以使用 id 方法来使用它。下面说明了可变对象的 id 方法的使用方法,如下所示:

Python Code:

mut_list = [1, 2, 3]
print("The list in Python",mut_list)
print("the id of the list is ",id(mut_list))
mut_list[0] = 'Gurru99'
mut_list
print("The mut list in Python after changing value",mut_list)
print("the id of the list is post change in value",id(mut_list))

输出

The list in Python [1, 2, 3]
the id of the list is 139931568729600
The list in Python after changing value ['Gurru99', 2, 3]
the id of the list is post change in value 139931568729600

下图说明了 Python 如下所示:-

中的可变对象 Python

不可变对象 Python

不可变对象 Python 是实例在一段时间内不会改变的对象。特定类型的不可变实例一旦创建就不会改变,可以使用 Python.

让我们以整数类型对象为例 Python 这说明了不可变对象的概念 Python 如下所示:-

Python Code:

a=244
print("the number before change is",a)
print("the id of number before change is",id(a))
a=344
print("the number after change is",a)
print("the id of number after change is",id(a))

输出

the number before a change is 244
the id of number before change is 9796768
the number before change is 344
the id of number before change is 140032307887024

从上图中可以看出,“a”发生了变化。让我们研究一下这个机制是如何工作的:

  • 当用344初始化“a”时,对象的值没有变化。
  • 相反,会创建一个新对象,并用“a”作为边界。
  • 指定为 244 的另一个对象将不再可访问。
  • 上面的例子利用了一个整数对象。

在 a=244 时,将创建一个新对象并引用“a”,如下所示:-

不可变对象 Python

使用 a=344 发布后,有一个引用“a”的新对象。下图表示相同的内容:–

不可变对象 Python

因此,每当为 int 类型的名称分配新值时,名称与另一个对象的绑定就会发生变化。同样的原则也适用于元组, 字符串、浮点数和布尔值因此被称为不可变的。

对字典键的含义 Python

字典可以定义为以键格式存储数据且不允许重复的有序集合。字典包含一个键,该键具有与之对齐的相应值对。它们的类型是可变的,即使在初始化和创建后,其内容也可以更改。

在任何时候,键都指向一个特定的元素。字典的键是不可变的。

让我们假设如下场景:

a = [4, 6]
b = [5, 6, 7]
my_dict = {a: 'x', b: 'y'}
print(my_dict)

输出:- 以上 Python 代码不会产生任何输出,而是生成一个不可哈希类型的类型错误。这是一种假设情况,在 Python 编译器。

在这里, a 定义为 [4,6],在字典中定义为 x。这里, b 定义为[5,6,7],在字典中定义为y。

  • 键 'a' 的值为 [4,6],并且进一步初始化为 x。
  • 键“b”的值为 [5,6,7],在字典中进一步初始化为“y”。
  • 现在假设'一种' 附加了 5 和 7,这是字典的键。
  • 那么字典就发生了变异,它会同时给出 'X''y' 作为上述字典的值。

考虑如上所示的以下场景:-

a = [5, 6,7]
b = [5, 6, 7]
my_dict = {a: 'x', b: 'y'}
print(my_dict)

因此,作为一种编程语言, Python 使字典的键不可变,并且字典是不可变的数据类型。

不变性的例外

然而, Python 提供不可变性的例外,对于元组对象类型可以观察到此类例外。元组可以是可变和不可变对象类型的组合。让我们举一个例子来解释不可变性中的例外,如下所示:-

Python Code:

tupexample=([1,1],'guru99')
print("the tuple before change",tupexample)
print("the id of tuple before change",id(tupexample))
tupexample=([2,2],'guru99')
print("the tuple after change",tupexample)
print("the id of tuple after change",id(tupexample))

输出:

the tuple before change ([1, 1], 'guru99')
the id of tuple before change 140649480694656
the tuple after change ([2, 2], 'guru99')
the id of tuple after change 140649480694592

您可以在上面的代码中看到,第一个元素(列表)是可变的,而元组是不可变的。元组的值不能更改,但元组中的列表的内容可以更改其值。

因此,这引发了一个异常,即不可变对象的值不会改变其值,但组成部分的值会改变其值。

可变对象与不可变对象

以下是可变对象和不可变对象之间的主要区别:

可变对象 不可变对象
对象状态一旦创建就可以改变 对象状态一旦创建就无法改变
可变对象本质上不被视为线程安全的。 不可变对象本质上被视为线程安全的。
可变对象不是最终的,因此程序员可以不断改变可变对象并使用相同的对象。 在创建不可变对象时,将类设为 final 至关重要

Python 不可变数据类型

增益级 说明 是否不可变
布尔 布尔值 不可变的
诠释 整数值(大小可以是任意的) 不可变的
Float 浮点数 不可变的
列表 可变性质的对象序列 可变的
元组 不可变性质的对象序列 不可变的
STR 字符/字符串 不可变的
一组具有无序性质的不同对象 可变的
冰雪奇缘 不可变性质的集合类 不可变的
字典 字典或关联图ping 可变的

常见问题

字符串是不可变的,因此它们的哈希值保持不变,可以用作字典的键或集合的成员。像 replace() 或 upper() 这样的方法会返回一个新字符串,而不是修改原始字符串。

元组是不可变的,所以 Python 可以对它们进行哈希处理,用于字典键,并保护固定数据免受意外更改。列表保持可变性,因为它们是为不断增长或缩减的集合而设计的。

像 def f(x, items=[]) 这样的可变默认值是有风险的: Python 列表只需创建一次,因此在函数调用之间保持不变。使用 items=None,然后在函数内部将 items 赋值为 []。

使用 copy 模块:copy.copy() 执行浅拷贝,嵌套对象共享;而 copy.deepcopy() 则复制每一层对象。切片或 list(original) 也会执行浅拷贝。

冻结集是集合的不可变版本。它不能添加或删除元素,因此它是可哈希的,可以用作字典的键或集合的元素。

不可变对象是可哈希的,因此它们可以用作字典的键和集合的成员。它们是线程安全的,更易于理解,并且支持诸如小整数驻留之类的优化。

数据科学依赖于可变结构:NumPy 数组、pandas DataFrame 和 PyTor为了提高速度,通道张量会原地发生变化。由于人工智能流程会共享这些张量, track 项就地编辑,以保持可复现性。

是的。GitHub Copilot 和 AI 助手会标记可变的默认参数,建议使用深度拷贝,并推荐使用元组或冻结集来存储常量数据。 Rev查看他们的输出,因为建议可能会忽略细微的就地突变错误。

总结一下这篇文章: