Hướng dẫn .copy deep true python - .copy deep true python

Mã nguồn: lib/copy.py Lib/copy.py


Các câu lệnh gán trong Python không sao chép các đối tượng, chúng tạo ra các ràng buộc giữa mục tiêu và đối tượng. Đối với các bộ sưu tập có thể thay đổi hoặc chứa các mục có thể thay đổi, đôi khi một bản sao là cần thiết để người ta có thể thay đổi một bản sao mà không thay đổi cái kia. Mô -đun này cung cấp các hoạt động sao chép nông và sâu chung (giải thích bên dưới).

Tóm tắt giao diện:

sao chép.Copy (x) ¶copy(x)

Trả lại một bản sao nông của x.

sao chép.deepcopy (x [, memo]) ¶deepcopy(x[, memo])

Trả lại một bản sao sâu của x.

ExceptionCopy.error¶ copy.Error

Được nâng lên cho các lỗi cụ thể của mô -đun.

Sự khác biệt giữa sao chép nông và sâu chỉ có liên quan đến các đối tượng hỗn hợp (các đối tượng có chứa các đối tượng khác, như danh sách hoặc trường hợp lớp):

  • Một bản sao nông xây dựng một đối tượng hợp chất mới và sau đó (trong phạm vi có thể) chèn các tham chiếu vào nó vào các đối tượng được tìm thấy trong bản gốc.

  • Một bản sao sâu xây dựng một đối tượng hợp chất mới và sau đó, đệ quy, chèn các bản sao vào nó của các đối tượng được tìm thấy trong bản gốc.

Hai vấn đề thường tồn tại với các hoạt động sao chép sâu mà don lồng tồn tại với các hoạt động sao chép nông:

  • Các đối tượng đệ quy (các đối tượng hợp chất, trực tiếp hoặc gián tiếp, chứa một tham chiếu đến chính chúng) có thể gây ra một vòng lặp đệ quy.

  • Bởi vì bản sao sâu sao chép mọi thứ mà nó có thể sao chép quá nhiều, chẳng hạn như dữ liệu dự định được chia sẻ giữa các bản sao.

Hàm deepcopy() tránh những vấn đề này bằng cách:

  • Giữ một từ điển memo của các đối tượng đã được sao chép trong quá trình sao chép hiện tại; và

  • Cho phép các lớp do người dùng xác định ghi đè hoạt động sao chép hoặc tập hợp các thành phần được sao chép.

Mô -đun này không sao chép các loại như mô -đun, phương thức, dấu vết ngăn xếp, khung ngăn xếp, tệp, ổ cắm, cửa sổ hoặc bất kỳ loại tương tự nào. Nó không sao chép các chức năng và các lớp (nông và sâu), bằng cách trả về đối tượng ban đầu không thay đổi; Điều này tương thích với cách chúng được xử lý bằng mô -đun pickle.

Các bản sao nông của từ điển có thể được thực hiện bằng cách sử dụng dict.copy() và các danh sách bằng cách gán một lát của toàn bộ danh sách, ví dụ, copied_list = original_list[:].

Các lớp có thể sử dụng các giao diện tương tự để kiểm soát sao chép mà họ sử dụng để kiểm soát Pickling. Xem mô tả của mô -đun pickle để biết thông tin về các phương pháp này. Trên thực tế, mô -đun copy sử dụng các hàm Pickle đã đăng ký từ mô -đun copyreg.

Để một lớp xác định triển khai bản sao của riêng mình, nó có thể xác định các phương thức đặc biệt

In[10]: arr1 = [1, 2, 3]
In[11]: arr2 = [1, 2, 3, 4]
In[12]: df1 = pd.DataFrame([[arr1], [arr2]], columns=['A'])
In[13]: df1.applymap(id)
Out[13]: 
            A
0  4515714832
1  4515734952

In[14]: df2 = df1.copy(deep=True)
In[15]: df2.applymap(id)
Out[15]: 
            A
0  4515714832
1  4515734952

In[16]: df2.loc[0, 'A'].append(55)
In[17]: df2
Out[17]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
In[18]: df1
Out[18]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
0 và
In[10]: arr1 = [1, 2, 3]
In[11]: arr2 = [1, 2, 3, 4]
In[12]: df1 = pd.DataFrame([[arr1], [arr2]], columns=['A'])
In[13]: df1.applymap(id)
Out[13]: 
            A
0  4515714832
1  4515734952

In[14]: df2 = df1.copy(deep=True)
In[15]: df2.applymap(id)
Out[15]: 
            A
0  4515714832
1  4515734952

In[16]: df2.loc[0, 'A'].append(55)
In[17]: df2
Out[17]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
In[18]: df1
Out[18]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
1. Cái trước được gọi để thực hiện hoạt động sao chép nông; Không có lập luận bổ sung được thông qua. Cái sau được gọi để thực hiện hoạt động sao chép sâu; Nó được thông qua một đối số, từ điển memo. Nếu việc triển khai
In[10]: arr1 = [1, 2, 3]
In[11]: arr2 = [1, 2, 3, 4]
In[12]: df1 = pd.DataFrame([[arr1], [arr2]], columns=['A'])
In[13]: df1.applymap(id)
Out[13]: 
            A
0  4515714832
1  4515734952

In[14]: df2 = df1.copy(deep=True)
In[15]: df2.applymap(id)
Out[15]: 
            A
0  4515714832
1  4515734952

In[16]: df2.loc[0, 'A'].append(55)
In[17]: df2
Out[17]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
In[18]: df1
Out[18]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
1 cần tạo một bản sao sâu của một thành phần, nó sẽ gọi hàm deepcopy() với thành phần là đối số đầu tiên và từ điển ghi nhớ là đối số thứ hai. Từ điển ghi nhớ nên được coi là một đối tượng mờ đục.

Xem thêm

Mô -đun pickle

Thảo luận về các phương pháp đặc biệt được sử dụng để hỗ trợ truy xuất và phục hồi trạng thái đối tượng.

Nếu bạn thấy ID đối tượng của các khung dữ liệu khác nhau mà bạn tạo, bạn có thể thấy rõ những gì đang xảy ra.

Khi bạn viết

In[10]: arr1 = [1, 2, 3]
In[11]: arr2 = [1, 2, 3, 4]
In[12]: df1 = pd.DataFrame([[arr1], [arr2]], columns=['A'])
In[13]: df1.applymap(id)
Out[13]: 
            A
0  4515714832
1  4515734952

In[14]: df2 = df1.copy(deep=True)
In[15]: df2.applymap(id)
Out[15]: 
            A
0  4515714832
1  4515734952

In[16]: df2.loc[0, 'A'].append(55)
In[17]: df2
Out[17]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
In[18]: df1
Out[18]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
6, bạn đang tạo một biến có tên
In[10]: arr1 = [1, 2, 3]
In[11]: arr2 = [1, 2, 3, 4]
In[12]: df1 = pd.DataFrame([[arr1], [arr2]], columns=['A'])
In[13]: df1.applymap(id)
Out[13]: 
            A
0  4515714832
1  4515734952

In[14]: df2 = df1.copy(deep=True)
In[15]: df2.applymap(id)
Out[15]: 
            A
0  4515714832
1  4515734952

In[16]: df2.loc[0, 'A'].append(55)
In[17]: df2
Out[17]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
In[18]: df1
Out[18]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
7 và liên kết nó với một đối tượng có ID
In[10]: arr1 = [1, 2, 3]
In[11]: arr2 = [1, 2, 3, 4]
In[12]: df1 = pd.DataFrame([[arr1], [arr2]], columns=['A'])
In[13]: df1.applymap(id)
Out[13]: 
            A
0  4515714832
1  4515734952

In[14]: df2 = df1.copy(deep=True)
In[15]: df2.applymap(id)
Out[15]: 
            A
0  4515714832
1  4515734952

In[16]: df2.loc[0, 'A'].append(55)
In[17]: df2
Out[17]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
In[18]: df1
Out[18]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
8.Khi bạn viết
In[10]: arr1 = [1, 2, 3]
In[11]: arr2 = [1, 2, 3, 4]
In[12]: df1 = pd.DataFrame([[arr1], [arr2]], columns=['A'])
In[13]: df1.applymap(id)
Out[13]: 
            A
0  4515714832
1  4515734952

In[14]: df2 = df1.copy(deep=True)
In[15]: df2.applymap(id)
Out[15]: 
            A
0  4515714832
1  4515734952

In[16]: df2.loc[0, 'A'].append(55)
In[17]: df2
Out[17]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
In[18]: df1
Out[18]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
9, bạn đang tạo một đối tượng mới với ID deepcopy()0 và liên kết nó với biến deepcopy()1, nhưng đối tượng có ID
In[10]: arr1 = [1, 2, 3]
In[11]: arr2 = [1, 2, 3, 4]
In[12]: df1 = pd.DataFrame([[arr1], [arr2]], columns=['A'])
In[13]: df1.applymap(id)
Out[13]: 
            A
0  4515714832
1  4515734952

In[14]: df2 = df1.copy(deep=True)
In[15]: df2.applymap(id)
Out[15]: 
            A
0  4515714832
1  4515734952

In[16]: df2.loc[0, 'A'].append(55)
In[17]: df2
Out[17]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
In[18]: df1
Out[18]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
8 trước đây bị ràng buộc với deepcopy()1 tiếp tục hoạt động.Nếu không có biến bị ràng buộc với đối tượng đó, nó sẽ được thu gom rác bởi Python.

In[33]: import pandas as pd
In[34]: df1 = pd.DataFrame([1,2,3,4,5])
In[35]: id(df1)
Out[35]: 4541269200

In[36]: df2 = df1
In[37]: id(df2)
Out[37]: 4541269200  # Same id as df1

In[38]: df3 = df1.copy()
In[39]: id(df3)
Out[39]: 4541269584  # New object, new id.

In[40]: df4 = df1.copy(deep=False)
In[41]: id(df4)
Out[41]: 4541269072  # New object, new id.

In[42]: df1 = pd.DataFrame([9, 9, 9])
In[43]: id(df1)
Out[43]: 4541271120  # New object created and bound to name 'df1'.

In[44]: id(df2)
Out[44]: 4541269200  # Old object's id not impacted.

Chỉnh sửa: Đã thêm vào ngày 30/7/2018

Sao chép sâu không hoạt động trong gấu trúc và các nhà phát triển xem xét đặt các đối tượng có thể thay đổi bên trong một khung dữ liệu như một phản xạ.Xem xét những điều sau:

In[10]: arr1 = [1, 2, 3]
In[11]: arr2 = [1, 2, 3, 4]
In[12]: df1 = pd.DataFrame([[arr1], [arr2]], columns=['A'])
In[13]: df1.applymap(id)
Out[13]: 
            A
0  4515714832
1  4515734952

In[14]: df2 = df1.copy(deep=True)
In[15]: df2.applymap(id)
Out[15]: 
            A
0  4515714832
1  4515734952

In[16]: df2.loc[0, 'A'].append(55)
In[17]: df2
Out[17]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
In[18]: df1
Out[18]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]

In[10]: arr1 = [1, 2, 3]
In[11]: arr2 = [1, 2, 3, 4]
In[12]: df1 = pd.DataFrame([[arr1], [arr2]], columns=['A'])
In[13]: df1.applymap(id)
Out[13]: 
            A
0  4515714832
1  4515734952

In[14]: df2 = df1.copy(deep=True)
In[15]: df2.applymap(id)
Out[15]: 
            A
0  4515714832
1  4515734952

In[16]: df2.loc[0, 'A'].append(55)
In[17]: df2
Out[17]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
In[18]: df1
Out[18]: 
               A
0  [1, 2, 3, 55]
1   [1, 2, 3, 4]
7, nếu đó là một bản sao sâu thực sự nên có ID mới cho các danh sách có trong đó.Kết quả là, khi bạn sửa đổi một danh sách bên trong DF2, nó cũng ảnh hưởng đến danh sách bên trong DF1, vì chúng là cùng một đối tượng.