zoukankan      html  css  js  c++  java
  • (一)Python入门-5函数:05参数的传递-可变对象-不可变对象-浅拷贝和深拷贝-不可变对象含可变子对象

    一:参数的传递

      函数的参数传递本质上就是:从实参到形参的赋值操作。 Python中“一切皆对象”, 所有的赋值操作都是“引用的赋值”。所以,Python中参数的传递都是“引用传递”,不 是“值传递”。具体操作时分为两类:

      1. 对“可变对象”进行“写操作”,直接作用于原对象本身。

      2. 对“不可变对象”进行“写操作”,会产生一个新的“对象空间”,并用新的值填 充这块空间。(起到其他语言的“值传递”效果,但不是“值传递”)

      可变对象有: 字典、列表、集合、自定义的对象等

      不可变对象有: 数字、字符串、元组、function等

    二:传递可变对象的引用

      传递参数是可变对象(例如:列表、字典、自定义的其他可变对象等),实际传递的还是对 象的引用。在函数体中不创建新的对象拷贝,而是可以直接修改所传递的对象。

     1 #传递可变参数
     2 a = [10,20]
     3 print(id(a))
     4 print(a)
     5 print('**********************')
     6 def test01(m):
     7     print(id(m))    #a和m是同一对象
     8     m.append(30)    #由于 m是可变对象,不创建对象拷贝,直接修改这个对象
     9     print(id(m))
    10 
    11 test01(a)
    12 print(a)

    三:传递不可变对象的引用

      传递参数是不可变对象(例如:int、float、字符串、元组、布尔值),实际传递的还是对 象的引用。在”赋值操作”时,由于不可变对象无法修改,系统会新创建一个对象。

     1 #传递不可变参数
     2 b = 100
     3 print('b:',id(b))
     4 print('********************')
     5 def test02(n):
     6     print('n:',id(n))   #传递进来的是a 对象的地址
     7     n = n+100           #由于 a是不可变对象,因此创建新的对象n
     8     print('n:',id(n))   #n已经变成了新的对象
     9     print(n)
    10 
    11 test02(b)
    12 print('b:',id(b))

      显然,通过id值我们可以看到 n和 a一开始是同一个对象。给 n赋值后,n是新的对象。

    四:浅拷贝和深拷贝

      为了更深入的了解参数传递的底层原理,我们需要了解“浅拷贝和深拷贝”。我们可以使用内置函数:copy(浅拷贝)、deepcopy(深拷贝)。

      浅拷贝:不拷贝子对象的内容,只是拷贝子对象的引用。

      深拷贝:会连子对象的内存也全部拷贝一份,对子对象的修改不会影响源对象

    #测试浅拷贝和深拷贝
    import copy
    
    def testCopy():
        '''测试浅拷贝'''
        a = [10,20,[5,6]]
        b = copy.copy(a)
        print('a:',a)
        print('b:',b)
        b.append(30)
        b[2].append(7)
        print('浅拷贝。。。。')
        print('a:',a)
        print('b:',b)
    def testDeepCopy():
        '''测试浅拷贝'''
        a = [10,20,[5,6]]
        b = copy.deepcopy(a)
        print('a:',a)
        print('b:',b)
        b.append(30)
        b[2].append(7)
        print('浅拷贝。。。。')
        print('a:',a)
        print('b:',b)
    
    testCopy()
    print('**********************************')
    testDeepCopy()

    五:传递不可变对象包含的子对象是可变的情况

    #传递不可变对象时:不可变对象中包含了可变子对象。则方法内修改了这个可变子对象的值,原对象也发生了变化
    
    a = (10,20,[5,6])    #定义了不可变对象元组a,里面包含了可变子对象列表[5,6]
    print('a:',id(a))
    def test01(m):
        print('m:',id(m))
        m[2][0] = 100
        print(m)
        print('m:',id(m))
    
    test01(a)
    print(a)
  • 相关阅读:
    还在使用golang 的map 做Json编码么?
    Golang 性能测试(2) 性能分析
    golang 性能测试 (1) 基准性能测试
    消息队列 NSQ 源码学习笔记 (五)
    消息队列 NSQ 源码学习笔记 (四)
    消息队列 NSQ 源码学习笔记 (三)
    消息队列 NSQ 源码学习笔记 (二)
    消息队列 NSQ 源码学习笔记 (一)
    你不知道的空格
    Supervisor 使用和进阶4 (Event 的使用)
  • 原文地址:https://www.cnblogs.com/jack-zh/p/10840338.html
Copyright © 2011-2022 走看看