(一)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)

 

posted on 2019-05-11 23:34  JACK#zhang  阅读(292)  评论(0编辑  收藏  举报