python深浅拷贝分析,nolocal关键字和生成器yield from讲解

目录

Day16:阶段总结

16.1 知识点补充

16.1.1 nolocal关键字

16.1.2 yield from(很少用)

16.1.3 深浅拷贝


Day16:阶段总结

16.1 知识点补充

16.1.1 nolocal关键字

nolocal关键字,用的比较少,此处作为了解即可。

name = 'root'
​
​
def outer():
    name = "大烧饼"      
​
    def inner():
        nonlocal name   # 把 name = "大烧饼"  改成 name = 123
        name = 123
​
    inner()
    print(name)
​
​
outer()
print(name)

global 关键字 改的是全局

nolocal 关键字 改的上级作用域

16.1.2 yield from(很少用)

在生成器部分我们了解了yield关键字,其在python3.3之后有引入了一个yield from。

def foo():
    yield 2
    yield 2
    yield 2
​
​
def func():
    yield 1
    yield 1
    yield 1
    yield from foo() # 执行到这,进入到foo函数中
    yield 1
    yield 1
​
​
for item in func():
    print(item)

yield from 可以让我们生成器函数,跳到另外一个生成器函数中继续执行,执行完回到自己函数中继续往下执行

16.1.3 深浅拷贝

浅拷贝

  • 不可变类型,不拷贝。

    import copy
    ​
    v1 = "大烧饼"
    print(id(v1)) # 140652260947312
    ​
    v2 = copy.copy(v1) 
    print(id(v2)) # 140652260947312

    按理说拷贝v1之后,v2的内存地址应该不同,但由于python内部优化机制,内存地址是相同的,因为对不可变类型而言,如果以后修改值,会重新创建一份数据,不会影响原数据,所以,不拷贝也无妨。

    • 可变类型,只拷贝第一层。

      import copy
      ​
      v1 = ["大烧饼", "root", [44, 55]]
      print(id(v1))  # 140405837216896
      print(id(v1[2]))  # 140405837214592
      ​
      v2 = copy.copy(v1)
      print(id(v2))  # 140405837214784
      print(id(v2[2]))  # 140405837214592

  • 深拷贝

    • 不可变类型,不拷贝

      import copy
      ​
      v1 = "大烧饼"
      print(id(v1))  # 140188538697072
      ​
      v2 = copy.deepcopy(v1)
      print(id(v2))  # 140188538697072

      特殊的元组:

      • 元组元素中无可变类型,不拷贝

        import copy
        ​
        v1 = ("大烧饼", "root")
        print(id(v1))  # 140243298961984
        ​
        v2 = copy.deepcopy(v1)
        print(id(v2))  # 140243298961984

      • 元素元素中有可变类型,找到所有【可变类型】或【含有可变类型的元组】 均拷贝一份

        import copy
        ​
        v1 = ("大烧饼", "root", [11, [44, 55], (11, 22), (11, [], 22), 33])
        v2 = copy.deepcopy(v1)
        ​
        print(id(v1))  # 140391475456384
        print(id(v2))  # 140391475456640
        ​
        print(id(v1[2]))  # 140352552779008
        print(id(v2[2]))  # 140352552920448
        ​
        print(id(v1[2][1]))  # 140642999940480
        print(id(v2[2][1]))  # 140643000088832
        ​
        print(id(v1[2][2]))  # 140467039914560
        print(id(v2[2][2]))  # 140467039914560
        ​
        print(id(v1[2][3]))  # 140675479841152
        print(id(v2[2][3]))  # 140675480454784

  • 可变类型,找到所有层级的 【可变类型】或【含有可变类型的元组】 均拷贝一份

    import copy
    ​
    v1 = ["大烧饼", "root", [11, [44, 55], (11, 22), (11, [], 22), 33]]
    v2 = copy.deepcopy(v1)
    ​
    print(id(v1))  # 140391475456384
    print(id(v2))  # 140391475456640
    ​
    print(id(v1[2]))  # 140352552779008
    print(id(v2[2]))  # 140352552920448
    ​
    print(id(v1[2][1]))  # 140642999940480
    print(id(v2[2][1]))  # 140643000088832
    ​
    print(id(v1[2][2]))  # 140467039914560
    print(id(v2[2][2]))  # 140467039914560
    ​
    print(id(v1[2][3]))  # 140675479841152
    print(id(v2[2][3]))  # 140675480454784
    import copy
    ​
    v1 = ["大烧饼", "root", [44, 55]]
    v2 = copy.deepcopy(v1)
    ​
    print(id(v1))  # 140405837216896
    print(id(v2))  # 140405837214784
    ​
    ​
    print(id(v1[2]))  # 140563140392256
    print(id(v2[2]))  # 140563140535744

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值