1. 程式人生 > >企鵝核心技術:Python3.7的copy模組

企鵝核心技術:Python3.7的copy模組

拷貝模組copy

作者:Shawn
python3.7
文件:
https://docs.python.org/3/library/copy.html

  • Python的拷貝模組提供的功能不是很多,但不代表不重要.

copy

copy.copy(x)
  • 返回一個淺拷貝.

deepcopy

copy.deepcopy(x)
  • 返回一個深拷貝.

拷貝詳解

  • 拷貝操作直接影響到程式能否正確按照設計思路執行.
  • 不正確的拷貝往往不報錯,而這也是很多bug的原因.
  • 這裡直接提供一個直觀的例子:
import copy
a = [1,2,3,4,['a','b']]

b = a                   # 賦值
c = a[:]                # 淺拷貝
d = copy.copy(a)        # 淺拷貝
e = copy.deepcopy(a)    # 深拷貝

a.append(5)
a[4].append('c')

print('a=',a)
print('b=',b)
print('c=',c)
print('d=',d)
print('e=',e)

============ RESTART: F:\PyWorkspace\Python100\100
examples\007.py ============ a= [1, 2, 3, 4, ['a', 'b', 'c'], 5] b= [1, 2, 3, 4, ['a', 'b', 'c'], 5] c= [1, 2, 3, 4, ['a', 'b', 'c']] d= [1, 2, 3, 4, ['a', 'b', 'c']] e= [1, 2, 3, 4, ['a', 'b']]
  • 毫不意外,Python中的直接賦值也只是傳遞物件,好比隔壁老王和你的關係.
  • 對於copy操作來說,拷貝只進行了一層,之後的引用關係依然保留.
  • 最徹底的拷貝操作是deepcopy.其功能與名字一樣,會遞迴深入你的物件,將其裡裡外外每個層次都拷貝一份.
class deepdark():
    def __init__(self):
        self.fantasy=list()
        self.fantasy.append('oh')
    def banana(self):
        print(self.fantasy)
    def boyNextDoor(self):
        self.fantasy.append('my shoulder')

====================== RESTART: F:\PyWorkspace\blank.py ======================

>>> import copy
>>> a=deepdark()
>>> b=[1,a]
>>> c=copy.copy(b)
>>> d=copy.deepcopy(b)

>>> a.boyNextDoor()
>>> a.banana()
['oh', 'my shoulder']
>>> b[1].banana()
['oh', 'my shoulder']
>>> c[1].banana()
['oh', 'my shoulder']
>>> d[1].banana()
['oh']
  • 這裡可以很容易發現,deepcopy對於類的拷貝是直接生成一個值相同的新物件.
>>> e=copy.copy(a)
>>> a.boyNextDoor()
>>> a.banana()
['oh', 'my shoulder', 'my shoulder']
>>> e.banana()
['oh', 'my shoulder', 'my shoulder']

>>> e.boyNextDoor()
>>> e.banana()
['oh', 'my shoulder', 'my shoulder', 'my shoulder']
>>> a.banana()
['oh', 'my shoulder', 'my shoulder', 'my shoulder']

>>> f=copy.deepcopy(a)
>>> a.boyNextDoor()
>>> a.banana()
['oh', 'my shoulder', 'my shoulder', 'my shoulder', 'my shoulder']
>>> f.banana()
['oh', 'my shoulder', 'my shoulder', 'my shoulder']
  • 所以,對於一個類的話,copy只是生成一個引用,而deepcopy才是進行復制.