• 深浅拷贝与异常处理


    Python深浅拷贝

    拷贝(赋值)

    当lt2为lt的拷贝对象时,lt内的可变化类型变化,lt2变化;lt内的不可变类型变化,lt2变化

    使用的是简单的赋值

    lt = [1, 2, 3]
    lt2 = lt
    
    lt.append(4)
    print(lt)
    # 因为列表是可变类型,所以lt的值变化,lt2的值也会跟着变化
    print(lt2)
    

    结果为:

    [1, 2, 3, 4]
    [1, 2, 3, 4]

    浅拷贝

    使用的是copy.copy()

    lt2没有变化的情况

    import copy
    lt = [1, 2, 3]
    lt2 = copy.copy(lt)
    
    lt.append(4)
    print(lt)  # [1, 2, 3, 4]
    print(lt2)  # [1, 2, 3]
    

    lt2变化的情况

    import copy
    lt = [1000, 2000, 3000, [4000, 5000, 6000]]
    print('id(lt)', id(lt))
    print('id(lt[0])', id(lt[0]))
    print('id(lt[1])', id(lt[1]))
    print('id(lt[2])', id(lt[2]))
    print('id(lt[3])', id(lt[3]))
    print('*' * 50)
    lt2 = copy.copy(lt)
    print('id(lt2)', id(lt2))
    print('id(lt2[0])', id(lt2[0]))
    print('id(lt2[1])', id(lt2[1]))
    print('id(lt2[2])', id(lt2[2]))
    print('id(lt2[3])', id(lt2[3]))
    
    结果为:
    id(lt) 2913392877192
    id(lt[0]) 2913390652080
    id(lt[1]) 2913390652048
    id(lt[2]) 2913390652272
    id(lt[3]) 2913392877256
    **************************************************
    id(lt2) 2913392875784
    id(lt2[0]) 2913390652080
    id(lt2[1]) 2913390652048
    id(lt2[2]) 2913390652272
    id(lt2[3]) 2913392877256
    

    可以发现虽说lt2是lt的复制,并且内存地址不同,但是其内的元素的地址是相同的

    之前已经试过,更改lt中的int类型值不会对lt2造成影响,那么列表呢

    lt[-1].append(7)
    print(lt)  # [1, 2, 3, [4, 5, 6, 7]]
    print(lt2)  # [1, 2, 3, [4, 5, 6, 7]]
    
    
    lt[0] += 1
    print(lt)
    print(lt2)
    

    结果为:

    [1000, 2000, 3000, [4000, 5000, 6000, 7]]
    [1000, 2000, 3000, [4000, 5000, 6000, 7]]
    [1001, 2000, 3000, [4000, 5000, 6000, 7]]
    [1000, 2000, 3000, [4000, 5000, 6000, 7]]

    可见,当lt2为lt的浅拷贝对象时,lt内的可变类型变化,lt2变化;lt内的不可变类型变化,lt2不变化

    深拷贝

    深拷贝一般用法为:copy.deepcopy()

    深拷贝和前拷贝又有什么区别呢?我们还是用代码一探究竟吧

    import copy
    lt = [1000, 2000, 3000, [4000, 5000, 6000]]
    print('id(lt)',id(lt))
    print('id(lt[0])', id(lt[0]))
    print('id(lt[1])', id(lt[1]))
    print('id(lt[2])', id(lt[2]))
    print('id(lt[3])', id(lt[3]))
    print('*' * 50)
    lt2 = copy.deepcopy(lt)
    print('id(lt2)',id(lt2))
    print('id(lt2[0])', id(lt2[0]))
    print('id(lt2[1])', id(lt2[1]))
    print('id(lt2[2])', id(lt2[2]))
    print('id(lt2[3])', id(lt2[3]))
    

    结果为:

    id(lt) 2125003250120
    id(lt[0]) 2125000777488
    id(lt[1]) 2125001026224
    id(lt[2]) 2125001026192
    id(lt[3]) 2125003249928


    id(lt2) 2125003251400
    id(lt2[0]) 2125000777488
    id(lt2[1]) 2125001026224
    id(lt2[2]) 2125001026192
    id(lt2[3]) 2125003251336


    [1000, 2000, 3000, [4000, 5000, 6000, 7]]
    [1000, 2000, 3000, [4000, 5000, 6000]]

    牢记拷贝/浅拷贝/深拷贝只针对可变数据类型

    但是虽然看似很重要,但是实际上的应用却不是很多。。

    异常处理

    异常:报错

    语法异常

    错误都是 SytaxError

    if  # SyntaxError
    0 = 1  # SyntaxError
    

    逻辑异常

    错误的类型往往不一样

    1/0		# ZeroDivisionError
    dic = {}
    print(dic['skldfj'])  # KeyError
    

    try方法

    try方法无法捕捉语法错误

    try:
        if
    except Exception as e:  # 语法错误无法捕捉
        print(e)
        
       会报错
    

    但是逻辑错误可以捕捉:

    print(1)
    try:  # 尝试
        num = input('输入一个值')  # 123124
        dic = {'0': 'a'}
        print(dic[num])  # dic['123124']
    
        print(3)  # 代码自上而下,上面会运行
        1 / int(num)  # 错误不影响其他的代码,报错马上终止try缩进里面的代码
        print(4)
    
    except ZeroDivisionError as e:  # 除此之外  # try里面的代码出了什么错误,就得用什么错误捕捉  # as是把错误赋值给e
        print('e:', e)
    except KeyError as e:  # 可以写多个except捕捉多个异常
        print('e:', e)
    结果为:
    1
    输入一个值123
    e: '123'
    

    except可以捕捉异常

    print(1)
    try:  # 尝试
        1 / 1
    except Exception as e:  # Exception可以捕捉任意异常
        print('e:', e)
    finally:  # 最终的意思,无论报不报错都会打印 明天讲文件处理的时候带着你用
        print(3)
    
    print(2)
    
    结果为:
    1
    3
    2
    

    finally无论报不报错都会打印

    raise

    主动抛错,一般用于创建框架/创建语言 c/c++有用

    print(1)
    raise ZeroDivisionError('傻逼吧,主动抛错干嘛')
    print(2)
    
    结果为:
    1
    Traceback (most recent call last):
      File "xxxx/xxx.py", line xx, in <module>
        raise ZeroDivisionError('傻逼吧,主动抛错干嘛')
    ZeroDivisionError: 傻逼吧,主动抛错干嘛
    

  • 相关阅读:
    redis 内存管理与数据淘汰机制(转载)
    Memcached特性及优缺点
    二叉树深度优先遍历和广度优先遍历
    电商 秒杀系统 设计思路和实现方法(转载)
    6种负载均衡算法
    解决like '%字符串%'时索引不被使用的方法
    哪些情况下索引会失效?
    PreferenceActivity详解
    sun.misc.BASE64Encoder在Eclipse中不能直接使用的原因和解决方案
    单点登录原理与简单实现
  • 原文地址:https://www.cnblogs.com/hyc123/p/11310950.html
Copyright © 2020-2023  润新知