Python中的可变对象和不可变对象详解

打印 上一主题 下一主题

主题 913|帖子 913|积分 2739

近来面试被问到了这个问题,写个帖子解释一下可变对象和不可变对象
  
1. 对象可变性简介

在Python中,每个变量都是一个对象,每个对象都具有其创建后是否允许修改的属性,这种特性称为对象的可变性。它影响对象在通报给函数、用于表达式或存储在数据结构中时的行为。
定义


  • 可变对象:创建后可以改变的对象。例子包罗列表、字典、集合和用户定义的对象。
  • 不可变对象:一旦创建后不允许被修改的对象。例子包罗整数、浮点数、字符串、元组和冻结集合。
2. 不可变对象的特性

不可变对象包罗数字(整数和浮点数)、字符串、元组等。这些对象的共同特点是一旦创建,它们的内存中的数据不可改变。
2.1 字符串

字符串是不可变对象的典范例子。当尝试修改字符串的内容时,Python并不是修改原有的字符串,而是创建一个新的字符串对象。
  1. str1 = "Hello"
  2. # 尝试更改字符串的内容
  3. str2 = str1.replace('H', 'J')
  4. print(str1)  # 输出 Hello,原字符串未改变
  5. print(str2)  # 输出 Jello,创建了一个新字符串
复制代码
2.2 整数和浮点数

整数和浮点数也是不可变对象。每次对数字进行修改,实际上是天生了一个新的数字对象。
  1. x = 10
  2. y = x
  3. x = x + 1
  4. print(y)  # 输出 10,y 仍然指向原来的整数对象
  5. print(x)  # 输出 11,x 现在指向一个新的整数对象
复制代码
2.3 元组

元组的不可变性示例
不能直接更改元组中的元素。假如尝试修改元组中的某个元素,Python 将抛出一个错误。
  1. tup = (1, 2, 3)
  2. try:
  3.     tup[0] = 100  # 尝试修改元组的第一个元素
  4. except TypeError as e:
  5.     print(e)  # 输出错误信息(TypeError)
复制代码
元组内含可变对象
尽管元组自己是不可变的,但假如元组中包罗可变对象,如列表,这些可变对象内部的内容是可以被修改的。这种环境下,元组的不可变性只适用于顶层结构,不影响内部元素的可变性。
  1. tup_with_list = (1, [2, 3], 4)
  2. tup_with_list[1].append(5)
  3. print(tup_with_list)  # 输出 (1, [2, 3, 5], 4)
复制代码
3. 可变对象的特性

可变对象如列表、字典和集合允许在对象创建后修改其内容。
3.1 列表

列表是最常见的可变对象之一。可以在列表中添加、删除或更改元素,而无需创建一个新的列表对象。
  1. lst = [1, 2, 3]
  2. lst.append(4)
  3. print(lst)  # 输出 [1, 2, 3, 4],列表内容被修改
复制代码
3.2 字典

字典也是一个可变对象。可以随时添加、删除或修改字典中的键值对。
  1. dic = {'a': 1, 'b': 2}
  2. dic['c'] = 3
  3. print(dic)  # 输出 {'a': 1, 'b': 2, 'c': 3},字典已更新
复制代码
3.3 集合

集合的可变性示例
创建一个简单的集合,演示如何向集合中添加和删除元素。
  1. # 创建一个初始集合
  2. my_set = {1, 2, 3}
  3. print("初始集合:", my_set)
  4. # 添加、移除元素
  5. my_set.add(4)
  6. my_set.remove(2)
  7. print("操作后的集合:", my_set)
复制代码
集合的操纵限制
尽管集合是可变的,但也有一些操纵上的限制。比方,集合只能包罗不可变(可哈希)的对象。因此不能将列表或另一个集互助为元素添加到集合中。
  1. nested_set = {1, 2, 3}
  2. try:
  3.     nested_set.add([4, 5, 6])  # 尝试添加列表到集合中
  4.     # nested_set.add({7, 8, 9})  # 尝试添加另一个集合到集合中
  5. except TypeError as e:
  6.     print(e)  # 输出错误信息
复制代码
4. 函数中的对象通报

理解Python中的参数通报方式——按引用通报(实际上是对象的引用地址通报)——是理解可变与不可变对象的关键。
4.1 不可变对象的通报

向函数通报不可变对象时,对该对象的任何修改都不会影响原始对象,由于实际上是创建了一个新的对象。
  1. def update_number(n):
  2.     n += 10
  3. x = 5
  4. update_number(x)
  5. print(x)  # 输出 5,原始值未改变
复制代码
4.2 可变对象的通报

相反,通报可变对象时,函数内对对象的修改将影响原始对象。
  1. def update_list(lst):
  2.     lst.append(4)
  3. my_list = [1, 2, 3]
  4. update_list(my_list)
  5. print(my_list)  # 输出 [1, 2, 3, 4],原始列表被修改
复制代码

   推荐: python 错误纪录
参考:Mutable vs Immutable Objects in Python

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

大连密封材料

金牌会员
这个人很懒什么都没写!
快速回复 返回顶部 返回列表