python2.7中對于不同的數(shù)據(jù)模型對于不同的復制方式會出現(xiàn)不一樣的結果,平時工作中遇到很多坑江滨,總結如下铛纬。
一、不可變數(shù)據(jù)模型(整型int唬滑、浮點型float告唆、字符串型string和元組tuple)
-
第1種:通過等號[=]復制
originalStr = 'nanjing'
anotherStr = originalStr # [=]號復制
print '復制前后是否為同一內存地址: %s' % (id(originalStr) == id(anotherStr))
nowCity = 'nantong'
print '原字符串: nanjing, 現(xiàn)字符串: %s' % originalStr
---
復制前后是否為同一內存地址: True
原字符串: nanjing, 現(xiàn)字符串: nanjing
-
第2種:通過工廠方法復制
originalStr = 'nanjing'
anotherStr = str(originalStr) # 通過str()
print '復制前后是否為同一內存地址: %s' % (id(originalStr) == id(anotherStr))
nowCity = 'nantong'
print '原字符串: nanjing, 現(xiàn)字符串: %s' % originalStr
---
復制前后是否為同一內存地址: True
原字符串: nanjing, 現(xiàn)字符串: nanjing
第3種:通過淺拷貝(copy)方法復制
import copy
originalStr = 'nanjing'
anotherStr = copy.copy(originalStr) # 淺拷貝,只拷貝頂級對象
print '復制前后是否為同一內存地址: %s' % (id(originalStr) == id(anotherStr))
nowCity = 'nantong'
print '原字符串: nanjing, 現(xiàn)字符串: %s' % originalStr
---
復制前后是否為同一內存地址: True
原字符串: nanjing, 現(xiàn)字符串: nanjing
第4種:通過深拷貝(deepcopy)方法復制
import copy
originalStr = 'nanjing'
anotherStr = copy.deepcopy(originalStr) # 深拷貝,拷貝頂級對象及嵌套對象
print '復制前后是否為同一內存地址: %s' % (id(originalStr) == id(anotherStr))
nowCity = 'nantong'
print '原字符串: nanjing, 現(xiàn)字符串: %s' % originalStr
---
復制前后是否為同一內存地址: True
原字符串: nanjing, 現(xiàn)字符串: nanjing
二晶密、可變數(shù)據(jù)模型列表list擒悬、字典dict
-
第1種:通過等號[=]復制
originalList = ['nanjing', [1, 2]]
anotherList = originalList # [=]號復制
print '復制前后是否為同一內存地址: %s' % (id(originalList) == id(anotherList))
anotherList[0] = 'nantong'
anotherList[1].append(3)
print "原列表: ['nanjing', [1, 2]], 現(xiàn)列表: %s" % originalList
--
復制前后是否為同一內存地址: True
原列表: ['nanjing', [1, 2]], 現(xiàn)列表: ['nantong', [1, 2, 3]]
-
第2種:通過工廠方法復制
originalList = ['nanjing', [1, 2]]
anotherList = list(originalList) # 通過list()復制
print '復制前后是否為同一內存地址: %s' % (id(originalList) == id(anotherList))
anotherList[0] = 'nantong'
anotherList[1].append(3)
print "原列表: ['nanjing', [1, 2]], 現(xiàn)列表: %s" % originalList
---
復制前后是否為同一內存地址: False
原列表: ['nanjing', [1, 2]], 現(xiàn)列表: ['nanjing', [1, 2, 3]]
-
第3種:通過[:](值傳遞)復制
originalList = ['nanjing', [1, 2]]
anotherList = originalList[:] # 通過[:]復制
print '復制前后是否為同一內存地址: %s' % (id(originalList) == id(anotherList))
anotherList[0] = 'nantong'
anotherList[1].append(3)
print "原列表: ['nanjing', [1, 2]], 現(xiàn)列表: %s" % originalList
---
復制前后是否為同一內存地址: False
原列表: ['nanjing', [1, 2]], 現(xiàn)列表: ['nanjing', [1, 2, 3]]
-
第4種:通過淺拷貝(copy)方法復制
import copy
originalList = ['nanjing', [1, 2]]
anotherList = copy.copy(originalList) # 淺拷貝,只拷貝頂級對象
print '復制前后是否為同一內存地址: %s' % (id(originalList) == id(anotherList))
anotherList[0] = 'nantong'
anotherList[1].append(3)
print "原列表: ['nanjing', [1, 2]], 現(xiàn)列表: %s" % originalList
---
復制前后是否為同一內存地址: False
原列表: ['nanjing', [1, 2]], 現(xiàn)列表: ['nanjing', [1, 2, 3]]
-
第5種:通過深拷貝(deepcopy)方法復制
import copy
originalList = ['nanjing', [1, 2]]
anotherList = copy.deepcopy(originalList) # 深拷貝,拷貝頂級對象及嵌套對象
print '復制前后是否為同一內存地址: %s' % (id(originalList) == id(anotherList))
anotherList[0] = 'nantong'
anotherList[1].append(3)
print "原列表: ['nanjing', [1, 2]], 現(xiàn)列表: %s" % originalList
---
復制前后是否為同一內存地址: False
原列表: ['nanjing', [1, 2]], 現(xiàn)列表: ['nanjing', [1, 2]]
初步總結
第1種:通過等號[=]復制
- 不論可變還是不可變數(shù)據(jù)類型稻艰,通過[=]復制后都指向同一個內存地址懂牧;
- 改變復制后的數(shù)據(jù)(例子中的anotherStr,anotherList),原數(shù)據(jù)中不可變數(shù)據(jù)模型值未改變尊勿,可變數(shù)據(jù)模型值改變
-
第2種:通過工廠方法復制
- 不可變數(shù)據(jù)模型復制后指向同一個內存地址僧凤,可變數(shù)據(jù)模型指向不同地址用狱;
- 改變復制后的數(shù)據(jù)(例子中的anotherStr,anotherList),原數(shù)據(jù)中不可變數(shù)據(jù)模型值未改變拼弃,可變數(shù)據(jù)模型值改變
-
第3種:通過[:](值傳遞)復制
- 不可變數(shù)據(jù)模型不涉及夏伊;可變數(shù)據(jù)模型指向不同內存地址;
- 改變復制后的數(shù)據(jù)(anotherList)吻氧,原數(shù)據(jù)中不可變數(shù)據(jù)模型值未改變溺忧,可變數(shù)據(jù)模型值改變
-
第4種:通過淺拷貝(copy)方法復制
- 不可變數(shù)據(jù)模型復制后指向同一個內存地址,可變數(shù)據(jù)模型指向不同地址盯孙;
- 改變復制后的數(shù)據(jù)(例子中的anotherStr,anotherList)鲁森,原數(shù)據(jù)中不可變數(shù)據(jù)模型值未改變,可變數(shù)據(jù)模型值改變
-
第5種:通過深拷貝(deepcopy)方法復制
- 不可變數(shù)據(jù)模型復制后指向同一個內存地址振惰,可變數(shù)據(jù)模型指向不同地址歌溉;
- 改變復制后的數(shù)據(jù)(例子中的anotherStr,anotherList),原數(shù)據(jù)中不可變骑晶、可變數(shù)據(jù)模型值均未改變
最終總結
- 對于不可變數(shù)據(jù)模型痛垛,不論通過什么辦法復制,通過改變復制后的數(shù)據(jù)桶蛔,均不會改變原數(shù)據(jù)的值
- 對于可變數(shù)據(jù)模型匙头,除深拷貝不會改變原數(shù)據(jù)值,其他均會改變原數(shù)據(jù)值