zoukankan      html  css  js  c++  java
  • 理解python可变类型vs不可变类型,深拷贝vs浅拷贝

    核心提示:

    可变类型 Vs 不可变类型

    可变类型(mutable):列表,字典

    不可变类型(unmutable):数字,字符串,元组

    这里的可变不可变,是指内存中的那块内容(value)是否可以被改变

    代码:

    name1='wupeiqi'
    name2=name1
    print("name1:%s
    name2:%s" %(name1,name2))
    name1='alex'
    print("I have assigned new value to name1.Let's see what happens to name2!")
    print("name1:%s
    name2:%s" %(name1,name2))

    执行结果:

    C:/Personal/OldboyPython/day01/test.py
    name1:wupeiqi
    name2:wupeiqi
    I have renamed name1 to new_name.Let's see what happens!
    name1:alex
    name2:wupeiqi

    疑问:为什么name2的值没有和name1一起变为alex?下面开始解答,先看图,后解释。

    以下引用自http://www.cnblogs.com/wupeiqi/articles/5433925.html

    变量的赋值

    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    name1 = "wupeiqi"
    name2 = "alex"
     
    #!/usr/bin/env python
    # -*- coding: utf-8 -*-
    
    name1 = "wupeiqi"   
    name2 = name1     # 使name2和name1指向同一个对象 赋值,只是创建一个变量,该变量指向原来内存地址,
     以上引用自http://www.cnblogs.com/wupeiqi/articles/5433925.html
     

    1.引用计数的增减

    当对象wupeiqi(图中蓝色的内存区块wupeiqi)被初次创建并(将其引用)赋值给变量name1时,对象wupeiqi的引用计数被设置为1。

    当对象alex(图中蓝色的内存区块alex)被初次创建并(将其引用)赋值给变量name2时,对象alex的引用计数被设置为1。

    当变量name1赋值给变量name2(name2=name1),实际是把对象wupeiqi赋值给name2,因此对象wupeiqi的引用计数自动加1,而对象alex的引用计数自动减1,即减为0,触发垃圾回收机制。

    2. 可变类型 Vs 不可变类型

    可变类型(mutable):列表,字典

    不可变类型(unmutable):数字,字符串,元组

    这里的可变不可变,是指内存中的那块内容(value)是否可以被改变。如果是不可变类型,在对对象本身操作的时候,必须在内存中新申请一块区域(因为老区域#不可变#)。如果是可变类型,对对象操作的时候,不需要再在其他地方申请内存,只需要在此对象后面连续申请(+/-)即可,也就是它的address会保持不变,但区域会变长或者变短。

    可以使用内建函数id()来确认对象的身份在两次赋值前后是否发生了变化。示例可参看http://blog.chinaunix.net/uid-26249349-id-3080279.html

    *不可变类型有什么好处?如果数据是不可变类型,当我们把数据传给一个不了解的API时,可以确保我们的数据不会被修改。如果我们要操作一个从函数返回的元组,可以通过内建函数list()把它转换成一个列表。(当被问到列表和元组的区别时,可以说这一点!)

    3. 深拷贝 Vs 浅拷贝

    copy.copy() 浅拷贝

    copy.deepcopy() 深拷贝

    copy与deepcopy是对于6种基础数据类型种的可变类型而言的,对于元组、字符串、数字这三种数据类型,不支持copy操作,deepcopy就更不支持了

     以下引用自http://www.cnblogs.com/wupeiqi/articles/5433925.html

    赋值,只是创建一个变量,该变量指向原来内存地址,如下例:

    n4 = n3 = n2 = n1 = "123/'Wu'"

    关于赋值,再看一个字典的例子:

    n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
    n2 = n1

     浅拷贝,在内存中只额外创建第一层数据,如下图

    import copy
    n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
    n3 = copy.copy(n1)

    深拷贝,在内存中将所有的数据重新创建一份(排除最后一层,即:python内部对字符串和数字的优化),如下图:

    import copy
    n1 = {"k1": "wu", "k2": 123, "k3": ["alex", 456]}
    n4 = copy.deepcopy(n1)

  • 相关阅读:
    《架构之美》阅读笔记六
    《架构之美》阅读笔记五
    软件工程——个人总结
    软件工程——团队作业4
    软件工程——团队答辩
    软件工程-团队作业3
    软件工程——团队作业2
    软件工程-团队作业1
    软件工程第二次作业——结对编程
    软件工程第一次作业补充
  • 原文地址:https://www.cnblogs.com/vincent-sh/p/12693782.html
Copyright © 2011-2022 走看看