likes
comments
collection
share

Python中的可变和不可变对象及使用方法

作者站长头像
站长
· 阅读数 40

在这篇文章中,我们已经解释了Python中Mutable和Immutable的概念,以及对象是如何受此影响的。我们提供了一些代码例子,让大家了解它是如何使用的。

在完成这篇文章后,你会明白:

  1. Python中的可变和不可变的对象
  2. 它们是如何和为什么被使用的?

简介:一切都是对象

在我们开始深入研究这些花哨的术语的含义之前,你需要知道这个。在Python中所有的东西都是一个对象

如果你不知道什么是对象,不用担心,现在只需了解对象可以是任何东西--一个整数、一个布尔值、一个列表等等。

那么一个简单的定义是:可变的对象可以被更新,不可变的对象不能被更新,试图更新它们会导致一个错误。

听起来很简单,不是吗?好吧,这里面还有很多东西,让我们深入了解一下!

正如我前面所说,由于Python中的一切都在一个对象中,我们在Python中创建的每一个变量都持有对象的实例(如果这个术语听起来很吓人,不要紧张,在我们前进的过程中你会理解这些概念)。

所以,正如我所说的,每个变量都持有一个对象的实例,因为Python是一种动态类型的语言,类型将在运行时被定义,它永远不会改变。但是,如果它是一个可变的对象,那么这个特定变量所持有的值就可以被改变。

可变和不可变的对象

在我们开始举例之前,让我们先看一下可变和不可变对象的几个例子:

可变对象:列表、集合和字典。 不可变的对象 :整数、浮点数、图元和字符串。

你可能在想,等等!整数和浮点数是不可变的?但是我总是改变一个变量的值,却没有看到错误?

嗯,这与python的内存管理有关,你看,当你在python中创建和初始化一个整数变量时,python为这个整数创造了足够的内存。这个变量只是指向它。当你试图改变一个变量的值时,实际发生的情况是,一个新的整数对象在内存中被创建,变量指向这个新对象。旧的整数对象将被python丢弃,如果它认为不再使用它的话。让我们看一个例子来更清楚地了解它。

我们将使用python中的**id()**函数。对于那些不熟悉这个函数的人来说,要明白它只是返回一个对象的身份(或者更简单地说,地址)(记住:在python中所有东西都是一个对象):

Python中的可变和不可变对象及使用方法

仔细看一下var1的标识,注意它在被分配到20之后的变化。这里它基本上是将指向从整数10转移到整数20。所以地址为18.....96的整数10的值不能被改变,因为整数是一个不可变的对象。

现在让我们继续讨论线性数据结构。所以在python中,我们有列表、集合、字符串和图元。让我们举一个可变对象和不可变对象的例子,比较它们是如何工作的。

让我们来看看一个操作,我们使用一个列表和一个元组。让我们试着在一个索引上更新一个值:

Python中的可变和不可变对象及使用方法

哦,等等!更新列表中的一个元素时没有出现错误,但是更新一个元组时却出现了TypeError。这就是我们在处理不可改变的对象时需要记住的东西。同样的情况也可以在字符串中观察到。请看下面的例子:

Python中的可变和不可变对象及使用方法

让我们深入了解一下列表的例子,让我们看看一个列表和它的地址,再看看更新后的地址:

Python中的可变和不可变对象及使用方法

这里我们可以清楚地看到,即使在更新了列表中的一个元素之后,列表的地址也没有被更新。但是请理解,list1[1]的地址在被更新后发生了变化。

但是,等等!如果我在更新像元组和字符串这样的不可变对象时得到一个错误,为什么我在串联两个字符串时没有得到一个错误?请看下面的例子:

Python中的可变和不可变对象及使用方法

你已经更新了string1,但是没有错误!为什么会这样?为什么会出现这种情况?为了理解这个问题,我们需要再次深入了解python中的内存管理方式。我将逐步解释上述代码中发生的情况:

  1. 一个字符串对象 "abc "被创建,变量string1指向其地址
  2. 现在,在连接阶段,实际发生的情况是,在一个新的内存位置复制了 "abc",将字符串 "def "附加到它上面,然后形成一个新的字符串 "abcdef"。
  3. 现在,变量string1只是指向新的字符串 "abcdef "而不是 "abc"。

Python中的可变和不可变对象及使用方法

仔细观察串联后string1的地址是如何变化的。在连接图元的过程中,也遵循类似的机制。重要的是要记住,就速度而言,这样的操作往往成本较高,因为在连接过程中,我们需要对对象进行复制,然后追加到它上面。

现在我将抛出一个有趣的声明。

不可变的对象不是完全不可变的

等等,什么?我在说什么?冷静一下,我将向你详细解释一切。现在让我们举一个非常有趣的例子来让你理解我的意思。

让一个元组 example = (23, [3,4,5])

请看下面的代码

Python中的可变和不可变对象及使用方法

我是如何更新一个元组的?所以这里有一个非常重要的语句,你需要理解。元组中的每个索引都被绑定到一个对象上(无论是int、float还是list),这些绑定是完全不可改变的,但是它们所绑定的对象,可以是可变的,也可以是不可改变的。

假设有一个整数元组,元组的每个索引被绑定到一个整数对象上,这个对象是不可变的,因此不可能更新元组。考虑另一种情况,即元组由列表组成,每个列表都是可变的,总是可以被更新。

这是一个非常重要的概念,要真正理解对象是如何分类为可变和不可变的核心。

这就是OpenGenus的这篇文章中关于可变和不可变对象的全部内容,以及它们在Python中的使用方法。

转载自:https://juejin.cn/post/7125727075717087262
评论
请登录