1. 程式人生 > >Python - 淺拷貝與深拷貝 - 再次整理

Python - 淺拷貝與深拷貝 - 再次整理

# -*- coding: UTF-8 -*-
import copy

def print_id(lst):
    lst_id = [id(y) for y in lst]
    lst_id.extend([id(y) for y in lst[1]])
    return str(lst_id)


def test_copy():
    Anndy = ['Anndy', ['age', 24]]
    Tom = Anndy[:]
    Cindy = list(Anndy)

    # 列印Anndy, Tom, Cindy容器元素的id
    print "Anndy: " + str(Anndy)
    print "Tom: " + str(Tom)
    print "Cindy: " + str(Cindy)
    print 'Anndy id: ' + print_id(Anndy)
    print 'Tom id: ' + print_id(Tom)
    print 'Cindy id: ' + print_id(Cindy)

    print '***修改不可變的變數值,名字***'
    Tom[0] = 'Tom'
    Cindy[0] = 'Cindy'
    print "Anndy: " + str(Anndy)
    print "Tom: " + str(Tom)
    print "Cindy: " + str(Cindy)
    print 'Anndy id: ' + print_id(Anndy)
    print 'Tom id: ' + print_id(Tom)
    print 'Cindy id: ' + print_id(Cindy)
    print "以上說明,修改不可變的變數值,不會影響其他物件"

    print '***修改可變的變數的值,改年齡為48***'
    Tom[1][1] = 48
    print "Anndy: " + str(Anndy)
    print "Tom: " + str(Tom)
    print "Cindy: " + str(Cindy)
    print 'Anndy id: ' + print_id(Anndy)
    print 'Tom id: ' + print_id(Tom)
    print 'Cindy id: ' + print_id(Cindy)
    print "以上說明,修改可變的變數的值,會影響其他物件的值,用不好這是會造成很大影響的"

    print "***深拷貝可以解決這個問題,如下:***"

    Anndy = ['Anndy', ['age', 24]]
    Tom = copy.deepcopy(Anndy)
    Cindy = copy.deepcopy(Anndy)

    print "Anndy: " + str(Anndy)
    print "Tom: " + str(Tom)
    print "Cindy: " + str(Cindy)
    # print '列印Anndy, Tom, Cindy容器元素的id'
    print 'Anndy id: ' + print_id(Anndy)
    print 'Tom id: ' + print_id(Tom)
    print 'Cindy id: ' + print_id(Cindy)
    print '修改Tom的年齡的值為68'
    Tom[1][1] = 68
    print "Anndy: " + str(Anndy)
    print "Tom: " + str(Tom)
    print "Cindy: " + str(Cindy)
    # print '列印Anndy, Tom, Cindy容器元素的id'
    print 'Anndy id: ' + print_id(Anndy)
    print 'Tom id: ' + print_id(Tom)
    print 'Cindy id: ' + print_id(Cindy)
    print '此次修改Tom的年齡沒有影響到Anndy和Cindy的年齡,同時觀察Anndy和Cindy的年齡的引用沒變,但是Tom的年齡的引用的id變了指向了物件68的地址'

if __name__ == '__main__':
    test_copy()

以上test_copy()的執行結果:
ssh://[email protected]:22/home/wfq/python27/bin/python -u /home/wfq/ops/test/my_copy.py
Anndy: [‘Anndy’, [‘age’, 24]]
Tom: [‘Anndy’, [‘age’, 24]]
Cindy: [‘Anndy’, [‘age’, 24]]
Anndy id: [140123118376256, 140123118857824, 140123118518064, 16486192]
Tom id: [140123118376256, 140123118857824, 140123118518064, 16486192]
Cindy id: [140123118376256, 140123118857824, 140123118518064, 16486192]
修改不可變的變數值,名字


Anndy: [‘Anndy’, [‘age’, 24]]
Tom: [‘Tom’, [‘age’, 24]]
Cindy: [‘Cindy’, [‘age’, 24]]
Anndy id: [140123118376256, 140123118857824, 140123118518064, 16486192]
Tom id: [140123118518104, 140123118857824, 140123118518064, 16486192] – Tom的名字的引用地址改變了,指向了物件’Tom’
Cindy id: [140123118376352, 140123118857824, 140123118518064, 16486192] – Cindy的名字的引用地址改變了,指向了物件’Cindy’
名字為字串,為不可變數,修改的時候會重新建立物件,僅僅包括原子物件的元組也屬於這種情況,那麼這樣沒有問題,還能節省記憶體

以上說明,修改不可變的變數值,不會影響其他物件
修改可變的變數的值,改年齡為48
Anndy: [‘Anndy’, [‘age’, 48]]
Tom: [‘Tom’, [‘age’, 48]]
Cindy: [‘Cindy’, [‘age’, 48]]
Anndy id: [140123118376256, 140123118857824, 140123118518064, 16487608]
Tom id: [140123118518104, 140123118857824, 140123118518064, 16487608]
Cindy id: [140123118376352, 140123118857824, 140123118518064, 16487608]
以上說明,修改可變的變數的值,會影響其他物件的值,用不好這是會造成很大影響的
年齡這個list是一個可變變數,修改他的值24為48的時候,這個list本身的引用地址140123118857824沒變,但是裡邊的值從指向到24物件的地址16486192改指向到了48這個物件的地址16487608
深拷貝可以解決這個問題,如下:
Anndy: [‘Anndy’, [‘age’, 24]]
Tom: [‘Anndy’, [‘age’, 24]]
Cindy: [‘Anndy’, [‘age’, 24]]
Anndy id: [140123118376256, 140123118857536, 140123118518064, 16486192]
Tom id: [140123118376256, 140123118388504, 140123118518064, 16486192]
Cindy id: [140123118376256, 140123118388576, 140123118518064, 16486192]
修改Tom的年齡的值為68
Anndy: [‘Anndy’, [‘age’, 24]]
Tom: [‘Anndy’, [‘age’, 68]]
Cindy: [‘Anndy’, [‘age’, 24]]
Anndy id: [140123118376256, 140123118857536, 140123118518064, 16486192]
Tom id: [140123118376256, 140123118388504, 140123118518064, 16487128]
Cindy id: [140123118376256, 140123118388576, 140123118518064, 16486192]
此次修改Tom的年齡沒有影響到Anndy和Cindy的年齡,同時觀察Anndy和Cindy的年齡的引用沒變,但是Tom的年齡的引用的id變了指向了物件68的地址16487128

Process finished with exit code 0