python赋值操作、浅拷贝、深拷贝以及函数传递参数详细解析

学过C语言的同学都能分清楚变量和指针的区别,而python的变量全部是指针的形式,所以在变量的赋值操作时(如a=b),只是将索引复制了一份。如果想把指针索引的内容进行复制, 则需要用到浅拷贝和深拷贝。下面来介绍一下python的赋值操作、浅拷贝和深拷贝的区别。

赋值操作

如果我们将变量b赋值为变量a,实质上是将变量b也指向了变量a所指向的对象。如下图所示:

python赋值操作、浅拷贝、深拷贝以及函数传递参数详细解析_第1张图片

所以我们改变该对象的内容时,不管再a还是b去所引,内容都已经改变。

import copy
class aclass(object):
    def __init__(self):
        self.list = [1, 2, [0, 0]]
        self.variable = 3

def main():
    a = aclass()
    b = a
    print(id(a), id(b), a is b)
    b.variable = 0
    print(a.variable)

if __name__ == '__main__':
    main()

执行结果为:
python赋值操作、浅拷贝、深拷贝以及函数传递参数详细解析_第2张图片

浅拷贝

浅拷贝操作的结果是只拷贝直接索引的对象,不会拷贝对象的内部的子对象。如下图所示:
python赋值操作、浅拷贝、深拷贝以及函数传递参数详细解析_第3张图片
浅拷贝后,我们改变变量b,则变量a的直接对象的值不会被改变,子对象的值会被改变。

import copy
class aclass(object):
    def __init__(self):
        self.list = [1, 2, ['a', 'b']]
        self.variable = 3

def main():
    a = aclass()
    b = copy.copy(a)
    print(id(a), id(b), a is b)
    b.variable = 0
    print(a.variable)
    b.list[0] = 0
    print(a.list[0])
    b.list[2][0] = 'c'
    print(a.list[2][0])

if __name__ == '__main__':
    main()

执行结果为:
在这里插入图片描述

深拷贝

深拷贝操作的结果是拷贝对象及其子对象。如下图所示:
python赋值操作、浅拷贝、深拷贝以及函数传递参数详细解析_第4张图片
深拷贝后,我们改变变量b,则变量a不受影响。

import copy
class aclass(object):
    def __init__(self):
        self.list = [1, 2, ['a', 'b']]
        self.variable = 3

def main():
    a = aclass()
    b = copy.deepcopy(a)
    print(id(a), id(b), a is b)
    b.variable = 0
    print(a.variable)
    b.list[0] = 0
    print(a.list[0])
    b.list[2][0] = 'c'
    print(a.list[2][0])

if __name__ == '__main__':
    main()

执行结果为:
在这里插入图片描述

函数传递参数属于哪种拷贝方式呢?

先说结论:函数传参属于赋值的方式。
可以通过一个简单的代码来验证:

import copy
class aclass(object):
    def __init__(self):
        self.list = [1, 2, ['a', 'b']]
        self.variable = 3

def fun(b):
    print(id(b))
    b.variable = 0

def main():
    a = aclass()
    print(id(a))
    fun(a)
    print(a.variable)

if __name__ == '__main__':
    main()

执行结果为:
在这里插入图片描述

你可能感兴趣的:(编程语言,python,编程语言)