翼度科技»论坛 编程开发 python 查看内容

Python中的可变对象与不可变对象

6

主题

6

帖子

18

积分

新手上路

Rank: 1

积分
18
Python中所有类型的值都是对象,这些对象分为可变对象与不可变对象两种:

  • 不可变类型
    float、int、str、tuple、bool、frozenset、bytes
    tuple自身不可变,但可能包含可变元素,如:([3, 4, 5], 'tuple')

  • 可变类型
    list、dict、set、bytearray、自定义类型
 
+=操作符

+=操作符对应__iadd__魔法方法,对于不可变对象,a+=b和a=a+b等价,对于可变对象并不等价,dict和set不支持+=和+操作符。
  1. l1 = l2 = [1, 2, 3]
  2. # 只有l1发生变化
  3. # l1 = l1 + [4]
  4. # l1和l2都发生变化,输出[1, 2, 3, 4, 5]
  5. l1 += [4, 5]
  6. print(l1)
  7. print(l2)
复制代码
 
浅拷贝 深拷贝

与赋值不同,拷贝(可能)会产生新的对象,可通过拷贝来避免不同对象间的相互影响。
在Python中,不可变对象,浅拷贝和深拷贝结果一样,都返回原对象:
  1. import copy
  2. t1 = (1, 2, 3)
  3. t2 = copy.copy(t1)
  4. t3 = copy.deepcopy(t1)
  5. print(t1 is t2) # True
  6. print(t1 is t3) # True
  7. print(id(t1), id(t2), id(t3)) # 输出相同值
复制代码
对于可变对象,则会产生新对象,只是若原对象中存在可变属性/字段,则浅拷贝产生的对象的属性/字段引用原对象的属性/字段,深拷贝产生的对象和原对象则完全独立:
  1. l1 = [1, 2, 3]
  2. l2 = l1.copy()
  3. print(l1 is l2)  # False
  4. l2[0] = 100
  5. print(l1[0])  # 1
复制代码
 
  1. import copy
  2. class Id:
  3.     def __init__(self, name):
  4.         self.name = name
  5. class Person:
  6.     def __init__(self, id: Id):
  7.         self.id = id
  8. p1 = Person(Id("eason"))
  9. p2 = copy.copy(p1)
  10. print(p1 is p2)  # False
  11. print(p1.id is p2.id)  # True
  12. p2.id.name = "p2"
  13. print(p1.id.name)  # p2
  14. p3 = copy.deepcopy(p1)
  15. print(p1 is p3)  # False
  16. print(p1.id is p3.id)  # False
  17. print(p1.id.name is p3.id.name)  # True,字符串不可变,这里name属性的地址一样
  18. p3.id.name = "p3"
  19. print(p1.id.name)  # 还是p2
复制代码
 
Python中可使用以下几种方式进行浅拷贝:

  • 使用copy模块的copy方法
  • 可变类型切片
    1. l1 = [1, 2, 3]
    2. l2 = l1[:]
    3. print(l1 is l2)  # False
    复制代码
     
  • 可变类型的copy方法
    1. [].copy()
    2. {}.copy()
    3. set().copy()
    复制代码
     
  • 调用list, set, dict方法
    1. l1 = [1, 2, 3]
    2. l2 = list(l1)
    3. l2[0] = 100
    4. print(l1[0])  # 1
    复制代码
     
推荐阅读

Different behaviour for list.__iadd__ and list.__add__
学习Python一年,这次终于弄懂了浅拷贝和深拷贝
copy — Shallow and deep copy operations

来源:https://www.cnblogs.com/Cwj-XFH/p/17308499.html
免责声明:由于采集信息均来自互联网,如果侵犯了您的权益,请联系我们【E-Mail:cb@itdo.tech】 我们会及时删除侵权内容,谢谢合作!

举报 回复 使用道具