Hướng dẫn python create copy of instance - python tạo bản sao của phiên bản

Làm cách nào để tạo một bản sao của một đối tượng trong Python?

Vì vậy, nếu tôi thay đổi giá trị của các trường của đối tượng mới, đối tượng cũ không nên bị ảnh hưởng bởi điều đó.

Show

Bạn có nghĩa là một đối tượng có thể thay đổi sau đó.

Trong Python 3, danh sách nhận được phương thức

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
6 (trong 2, bạn sẽ sử dụng một lát để tạo một bản sao):

>>> a_list = list('abc')
>>> a_copy_of_a_list = a_list.copy()
>>> a_copy_of_a_list is a_list
False
>>> a_copy_of_a_list == a_list
True

Bản sao nông

Bản sao nông chỉ là bản sao của container ngoài cùng.

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
7 là một bản sao nông:

>>> list_of_dict_of_set = [{'foo': set('abc')}]
>>> lodos_copy = list_of_dict_of_set.copy()
>>> lodos_copy[0]['foo'].pop()
'c'
>>> lodos_copy
[{'foo': {'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]

Bạn không nhận được một bản sao của các đối tượng nội thất. Chúng là cùng một đối tượng - vì vậy khi chúng bị đột biến, sự thay đổi hiển thị trong cả hai container.

Bản sao sâu

Bản sao sâu là bản sao đệ quy của mỗi đối tượng nội thất.

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]

Thay đổi không được phản ánh trong bản gốc, chỉ trong bản sao.

Đối tượng bất biến

Các đối tượng bất biến thường không cần phải sao chép. Trên thực tế, nếu bạn cố gắng, Python sẽ chỉ cung cấp cho bạn đối tượng ban đầu:

>>> a_tuple = tuple('abc')
>>> tuple_copy_attempt = a_tuple.copy()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'tuple' object has no attribute 'copy'

Tuples thậm chí không có một phương thức sao chép, vì vậy hãy thử nó bằng một lát:

>>> tuple_copy_attempt = a_tuple[:]

Nhưng chúng ta thấy đó là cùng một đối tượng:

>>> tuple_copy_attempt is a_tuple
True

Tương tự cho chuỗi:

>>> s = 'abc'
>>> s0 = s[:]
>>> s == s0
True
>>> s is s0
True

và đối với Frozensets, mặc dù chúng có phương pháp

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
6:

>>> a_frozenset = frozenset('abc')
>>> frozenset_copy_attempt = a_frozenset.copy()
>>> frozenset_copy_attempt is a_frozenset
True

Khi nào nên sao chép các đối tượng bất biến

Các đối tượng bất biến nên được sao chép nếu bạn cần một đối tượng nội thất có thể thay đổi được sao chép.

>>> tuple_of_list = [],
>>> copy_of_tuple_of_list = tuple_of_list[:]
>>> copy_of_tuple_of_list[0].append('a')
>>> copy_of_tuple_of_list
(['a'],)
>>> tuple_of_list
(['a'],)
>>> deepcopy_of_tuple_of_list = copy.deepcopy(tuple_of_list)
>>> deepcopy_of_tuple_of_list[0].append('b')
>>> deepcopy_of_tuple_of_list
(['a', 'b'],)
>>> tuple_of_list
(['a'],)

Như chúng ta có thể thấy, khi đối tượng bên trong của bản sao bị đột biến, bản gốc không thay đổi.

Đối tượng tùy chỉnh

Các đối tượng tùy chỉnh thường lưu trữ dữ liệu trong thuộc tính

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
9 hoặc trong
>>> a_tuple = tuple('abc')
>>> tuple_copy_attempt = a_tuple.copy()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'tuple' object has no attribute 'copy'
0 (cấu trúc bộ nhớ giống như tuple.)

Để tạo một đối tượng có thể sao chép, hãy xác định

>>> a_tuple = tuple('abc')
>>> tuple_copy_attempt = a_tuple.copy()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'tuple' object has no attribute 'copy'
1 (cho các bản sao nông) và/hoặc
>>> a_tuple = tuple('abc')
>>> tuple_copy_attempt = a_tuple.copy()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'tuple' object has no attribute 'copy'
2 (cho các bản sao sâu).

from copy import copy, deepcopy

class Copyable:
    __slots__ = 'a', '__dict__'
    def __init__(self, a, b):
        self.a, self.b = a, b
    def __copy__(self):
        return type(self)(self.a, self.b)
    def __deepcopy__(self, memo): # memo is a dict of id's to copies
        id_self = id(self)        # memoization avoids unnecesary recursion
        _copy = memo.get(id_self)
        if _copy is None:
            _copy = type(self)(
                deepcopy(self.a, memo), 
                deepcopy(self.b, memo))
            memo[id_self] = _copy 
        return _copy

Lưu ý rằng

>>> a_tuple = tuple('abc')
>>> tuple_copy_attempt = a_tuple.copy()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'tuple' object has no attribute 'copy'
3 giữ một từ điển ghi nhớ của
>>> a_tuple = tuple('abc')
>>> tuple_copy_attempt = a_tuple.copy()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'tuple' object has no attribute 'copy'
4 (hoặc số nhận dạng) cho các bản sao. Để tận hưởng hành vi tốt với các cấu trúc dữ liệu đệ quy, hãy chắc chắn rằng bạn đã không tạo một bản sao và nếu bạn có, hãy trả lại điều đó.

Vì vậy, hãy tạo một đối tượng:

>>> list_of_dict_of_set = [{'foo': set('abc')}]
>>> lodos_copy = list_of_dict_of_set.copy()
>>> lodos_copy[0]['foo'].pop()
'c'
>>> lodos_copy
[{'foo': {'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
0

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
6 tạo ra một bản sao nông:

>>> list_of_dict_of_set = [{'foo': set('abc')}]
>>> lodos_copy = list_of_dict_of_set.copy()
>>> lodos_copy[0]['foo'].pop()
'c'
>>> lodos_copy
[{'foo': {'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
1

>>> a_tuple = tuple('abc')
>>> tuple_copy_attempt = a_tuple.copy()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'tuple' object has no attribute 'copy'
3 bây giờ tạo ra một bản sao sâu:

>>> list_of_dict_of_set = [{'foo': set('abc')}]
>>> lodos_copy = list_of_dict_of_set.copy()
>>> lodos_copy[0]['foo'].pop()
'c'
>>> lodos_copy
[{'foo': {'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
2

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.

Làm thế nào để bạn tạo một bản sao sâu của một đối tượng trong Python?

Để tạo một bản sao sâu, hãy sử dụng hàm DeepCopy () của mô -đun sao chép. Trong một bản sao sâu, các bản sao được chèn thay vì các tham chiếu đến các đối tượng, do đó, việc thay đổi cái này không thay đổi cái kia.

Sao chép một đối tượng trong Python

Trong Python, chúng tôi sử dụng toán tử
>>> a_tuple = tuple('abc')
>>> tuple_copy_attempt = a_tuple.copy()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'tuple' object has no attribute 'copy'
7 để tạo một bản sao của một đối tượng. Bạn có thể nghĩ rằng điều này tạo ra một đối tượng mới; nó không. Nó chỉ tạo ra một biến mới chia sẻ tham chiếu của đối tượng gốc.

Hãy lấy một ví dụ trong đó chúng tôi tạo một danh sách có tên Old_list và chuyển một tham chiếu đối tượng đến new_list bằng toán tử

>>> a_tuple = tuple('abc')
>>> tuple_copy_attempt = a_tuple.copy()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: 'tuple' object has no attribute 'copy'
7.

>>> list_of_dict_of_set = [{'foo': set('abc')}]
>>> lodos_copy = list_of_dict_of_set.copy()
>>> lodos_copy[0]['foo'].pop()
'c'
>>> lodos_copy
[{'foo': {'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
4

Ví dụ 1: Sao chép bằng cách sử dụng = toán tử

>>> list_of_dict_of_set = [{'foo': set('abc')}]
>>> lodos_copy = list_of_dict_of_set.copy()
>>> lodos_copy[0]['foo'].pop()
'c'
>>> lodos_copy
[{'foo': {'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
3


Khi chúng tôi chạy trên chương trình, đầu ra sẽ là:

  1. Như bạn có thể thấy từ đầu ra, cả hai biến Old_List và New_list chia sẻ cùng một ID i.e
    >>> a_tuple = tuple('abc')
    >>> tuple_copy_attempt = a_tuple.copy()
    Traceback (most recent call last):
      File "", line 1, in 
    AttributeError: 'tuple' object has no attribute 'copy'
    
    9.
  2. Sao chép sâu

Vì vậy, nếu bạn muốn sửa đổi bất kỳ giá trị nào trong new_list hoặc old_list, thay đổi có thể nhìn thấy trong cả hai.


Về cơ bản, đôi khi bạn có thể muốn có các giá trị ban đầu không thay đổi và chỉ sửa đổi các giá trị mới hoặc ngược lại. Trong Python, có hai cách để tạo bản sao:

Bản sao nông

>>> list_of_dict_of_set = [{'foo': set('abc')}]
>>> lodos_copy = list_of_dict_of_set.copy()
>>> lodos_copy[0]['foo'].pop()
'c'
>>> lodos_copy
[{'foo': {'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
5

Để làm cho các bản sao này hoạt động, chúng tôi sử dụng mô -đun

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
6.


Như bạn có thể thấy từ đầu ra, cả hai biến Old_List và New_list chia sẻ cùng một ID i.e >>> a_tuple = tuple('abc') >>> tuple_copy_attempt = a_tuple.copy() Traceback (most recent call last): File "", line 1, in AttributeError: 'tuple' object has no attribute 'copy' 9.

Vì vậy, nếu bạn muốn sửa đổi bất kỳ giá trị nào trong new_list hoặc old_list, thay đổi có thể nhìn thấy trong cả hai.

Về cơ bản, đôi khi bạn có thể muốn có các giá trị ban đầu không thay đổi và chỉ sửa đổi các giá trị mới hoặc ngược lại. Trong Python, có hai cách để tạo bản sao:

Bản sao nông

>>> list_of_dict_of_set = [{'foo': set('abc')}]
>>> lodos_copy = list_of_dict_of_set.copy()
>>> lodos_copy[0]['foo'].pop()
'c'
>>> lodos_copy
[{'foo': {'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
6

Để làm cho các bản sao này hoạt động, chúng tôi sử dụng mô -đun

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
6.

>>> list_of_dict_of_set = [{'foo': set('abc')}]
>>> lodos_copy = list_of_dict_of_set.copy()
>>> lodos_copy[0]['foo'].pop()
'c'
>>> lodos_copy
[{'foo': {'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
7

Sao chép mô -đun

Chúng tôi sử dụng mô -đun

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
6 của Python cho các hoạt động sao chép nông và sâu. Giả sử, bạn cần sao chép danh sách hỗn hợp nói x. Ví dụ:

Ở đây,

>>> tuple_copy_attempt = a_tuple[:]
2 trả về một bản sao nông của x. Tương tự,
>>> tuple_copy_attempt = a_tuple[:]
3 Trả về một bản sao sâu của x.


Một bản sao nông tạo ra một đối tượng mới lưu trữ tham chiếu của các phần tử gốc.

>>> list_of_dict_of_set = [{'foo': set('abc')}]
>>> lodos_copy = list_of_dict_of_set.copy()
>>> lodos_copy[0]['foo'].pop()
'c'
>>> lodos_copy
[{'foo': {'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
8

Khi chúng tôi chạy chương trình, nó sẽ xuất hiện:

>>> list_of_dict_of_set = [{'foo': set('abc')}]
>>> lodos_copy = list_of_dict_of_set.copy()
>>> lodos_copy[0]['foo'].pop()
'c'
>>> lodos_copy
[{'foo': {'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
9

Trong chương trình trên, chúng tôi sử dụng hàm

>>> tuple_copy_attempt = a_tuple[:]
3 để tạo bản sao trông tương tự.

Tuy nhiên, khi bạn thay đổi bất kỳ đối tượng lồng nhau nào trong Old_list, các thay đổi sẽ xuất hiện trong new_list.


Ví dụ 4: Thêm đối tượng lồng nhau mới bằng cách sử dụng bản sao nông cạn

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
0

Khi chúng tôi chạy chương trình, nó sẽ xuất hiện:

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
1

Trong chương trình trên, chúng tôi đã thực hiện các thay đổi đối với Old_List I.E

>>> tuple_copy_attempt = a_tuple[:]
6. Cả hai người phụ của Old_List và New_List tại Index
>>> tuple_copy_attempt = a_tuple[:]
7 đã được sửa đổi. Điều này là do, cả hai danh sách đều chia sẻ tham chiếu của cùng các đối tượng lồng nhau.


Sao chép sâu

Một bản sao sâu tạo ra một đối tượng mới và thêm các bản sao của các đối tượng lồng nhau có trong các yếu tố gốc.

Tuy nhiên, hãy tiếp tục với ví dụ 2. Tuy nhiên, chúng tôi sẽ tạo bản sao sâu bằng hàm

>>> tuple_copy_attempt = a_tuple[:]
3 có trong mô -đun
>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
6. Bản sao sâu tạo ra bản sao độc lập của đối tượng gốc và tất cả các đối tượng lồng nhau của nó.

Ví dụ 5: Sao chép danh sách bằng DeepCopy ()

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
2

Khi chúng tôi chạy chương trình, nó sẽ xuất hiện:

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
3

Trong chương trình trên, chúng tôi đã thực hiện các thay đổi đối với Old_List I.E

>>> tuple_copy_attempt = a_tuple[:]
6. Cả hai người phụ của Old_List và New_List tại Index
>>> tuple_copy_attempt = a_tuple[:]
7 đã được sửa đổi. Điều này là do, cả hai danh sách đều chia sẻ tham chiếu của cùng các đối tượng lồng nhau.

Sao chép sâu


Một bản sao sâu tạo ra một đối tượng mới và thêm các bản sao của các đối tượng lồng nhau có trong các yếu tố gốc.

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
4

Khi chúng tôi chạy chương trình, nó sẽ xuất hiện:

>>> lodos_deep_copy = copy.deepcopy(list_of_dict_of_set)
>>> lodos_deep_copy[0]['foo'].add('c')
>>> lodos_deep_copy
[{'foo': {'c', 'b', 'a'}}]
>>> list_of_dict_of_set
[{'foo': {'b', 'a'}}]
5

Trong chương trình trên, chúng tôi đã thực hiện các thay đổi đối với Old_List I.E

>>> tuple_copy_attempt = a_tuple[:]
6. Cả hai người phụ của Old_List và New_List tại Index
>>> tuple_copy_attempt = a_tuple[:]
7 đã được sửa đổi. Điều này là do, cả hai danh sách đều chia sẻ tham chiếu của cùng các đối tượng lồng nhau.

Làm thế nào để bạn sao chép một thể hiện trong Python?

Sao chép một đối tượng trong Python trong Python, chúng tôi sử dụng toán tử = Toán tử để tạo một bản sao của một đối tượng. Bạn có thể nghĩ rằng điều này tạo ra một đối tượng mới; nó không. Nó chỉ tạo ra một biến mới chia sẻ tham chiếu của đối tượng gốc.use = operator to create a copy of an object. You may think that this creates a new object; it doesn't. It only creates a new variable that shares the reference of the original object.

Bạn có thể sao chép một thể hiện của một lớp trong Python không?

Có, bạn có thể sử dụng Copy.DeepCopy.Vì vậy, chỉ C2 = Sao chép. deepcopy . so just c2 = copy.

Copy () làm gì trong Python?

Định nghĩa và cách sử dụng.Phương thức Copy () trả về một bản sao của danh sách được chỉ định.returns a copy of the specified list.

Sự khác biệt giữa Copy và DeepCopy trong Python là gì?

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.

Làm thế nào để bạn tạo một bản sao sâu của một đối tượng trong Python?

Để tạo một bản sao sâu, hãy sử dụng hàm DeepCopy () của mô -đun sao chép.Trong một bản sao sâu, các bản sao được chèn thay vì các tham chiếu đến các đối tượng, do đó, việc thay đổi cái này không thay đổi cái kia.use the deepcopy() function of the copy module. In a deep copy, copies are inserted instead of references to objects, so changing one does not change the other.