Python copy class method

copy — Shallow and deep copy operations¶

Assignment statements in Python do not copy objects, they create bindings between a target and an object. For collections that are mutable or contain mutable items, a copy is sometimes needed so one can change one copy without changing the other. This module provides generic shallow and deep copy operations (explained below).

Return a shallow copy of x.

Raised for module specific errors.

The difference between shallow and deep copying is only relevant for compound objects (objects that contain other objects, like lists or class instances):

  • A shallow copy constructs a new compound object and then (to the extent possible) inserts references into it to the objects found in the original.
  • A deep copy constructs a new compound object and then, recursively, inserts copies into it of the objects found in the original.

Two problems often exist with deep copy operations that don’t exist with shallow copy operations:

  • Recursive objects (compound objects that, directly or indirectly, contain a reference to themselves) may cause a recursive loop.
  • Because deep copy copies everything it may copy too much, such as data which is intended to be shared between copies.

The deepcopy() function avoids these problems by:

  • keeping a memo dictionary of objects already copied during the current copying pass; and
  • letting user-defined classes override the copying operation or the set of components copied.

This module does not copy types like module, method, stack trace, stack frame, file, socket, window, or any similar types. It does “copy” functions and classes (shallow and deeply), by returning the original object unchanged; this is compatible with the way these are treated by the pickle module.

Shallow copies of dictionaries can be made using dict.copy() , and of lists by assigning a slice of the entire list, for example, copied_list = original_list[:] .

Classes can use the same interfaces to control copying that they use to control pickling. See the description of module pickle for information on these methods. In fact, the copy module uses the registered pickle functions from the copyreg module.

In order for a class to define its own copy implementation, it can define special methods __copy__() and __deepcopy__() . The former is called to implement the shallow copy operation; no additional arguments are passed. The latter is called to implement the deep copy operation; it is passed one argument, the memo dictionary. If the __deepcopy__() implementation needs to make a deep copy of a component, it should call the deepcopy() function with the component as first argument and the memo dictionary as second argument. The memo dictionary should be treated as an opaque object.

Читайте также:  Отключить php undefined variable

Discussion of the special methods used to support object state retrieval and restoration.

Источник

Глубокое и поверхностное копирование объектов в Python

В этом руководстве мы рассмотрим поверхностное и глубокое копирование с помощью Python. Обычно мы используем =(оператор присваивания) для создания копии объекта Python. Давайте разберемся с полной концепцией, связанной с созданием копий в Python.

Копирование в Python

Как мы все знаем, оператор присваивания используется для создания копии объекта Python, но это неверно; он только создает привязку между целью и объектом. Когда мы используем оператор присваивания, вместо создания нового объекта он создает новую переменную, которая использует ссылку на старый объект.

Копии нужны, когда пользователь хочет внести изменения, не изменяя при этом исходный объект. Пользователь также предпочитает создавать копию для работы с изменяемыми объектами.

Давайте разберемся в следующем примере.

list1 = [[1, 2, 3], [4, 5, 6], [7, 8, 'a']] list2 = list1 list2[1][2] = 4 print('Old List:', list1) print('ID of Old List:', id(list1)) print('New List:', list2) print('ID of New List:', id(list2))
Old List: [[1, 2, 3], [4, 5, 4], [7, 8, 'a']] ID of Old List: 1909447368968 New List: [[1, 2, 3], [4, 5, 4], [7, 8, 'a']] ID of New List: 1909447368968

В приведенном выше выводе мы видим, что обе переменные list1 и list2 имеют один и тот же идентификатор 1909447368968.

Если мы внесем какие-либо изменения в любое значение в list1 или list2, эти изменения отразятся на обоих.

Типы копий в Python

Основной мотив – создать копию объекта Python, которую мы можем изменить, не изменяя исходные данные. В Python есть два метода создания копий.

Читайте также:  Передача значений переменных

Мы будем использовать модуль копирования для создания вышеуказанных копий.

Модуль копирования

Модуль copy используется для создания мелкой и глубокой копии. Давайте посмотрим на каждый из его методов.

Мелкая копия

Неглубокая копия – это копия объекта, в которой хранятся ссылки на исходные элементы. Он создает новый объект коллекции и затем занимает его со ссылкой на дочерние объекты, найденные в оригинале.

Делает копии ссылки на вложенные объекты и не создает копии вложенных объектов. Поэтому, если мы внесем какие-либо изменения в копию объекта, это отразится на исходном объекте. Мы будем использовать функцию copy() для его реализации.

# importing "copy" for copy operations import copy # initializing list 1 list1 = [1, 7, [3,5], 8] # using copy to shallow copy list2 = copy.copy(list1) # original elements of list print("The original elements before shallow copying") for i in range(0,len(list1)): print(list1[i],end=" ") print("\r") # adding and element to new list list2[2][0] = 10 # checking if change is reflected print("The original elements after shallow copying") for i in range(0,len( list1)): print(list1[i],end=" ")
The original elements before shallow copying 1 7 [3, 5] 8 The original elements after shallow copying 1 7 [10, 5] 8

В приведенном выше коде мы сделали изменение в list1, который отражен в другом списке.

import copy list1 = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]] list2 = copy.copy(list1) list1.append([13, 14,15]) print("Old list:", list1) print("New list:", list2)
Old list: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12], [13, 14, 15]] New list: [[1, 2, 3], [4, 5, 6], [7, 8, 9], [10, 11, 12]]

В приведенном выше коде мы создали неглубокую копию list1. Вновь созданный список 2 содержит ссылку на исходный вложенный объект, хранящийся в списке 1. Затем мы добавили [13, 14, 15] в старый список и подсписок, не скопированный в новый список.

Глубокая копия на Python

Глубокая копия – это процесс, в котором мы создаем новый объект и рекурсивно добавляем элементы копии. Мы будем использовать метод deecopy(), который присутствует в модуле копирования. Независимая копия создается из исходного цельного объекта. Давайте разберемся в следующем примере.

import copy x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] z = copy.deepcopy(xs) print(x) prin(z)
[[1, 2, 3], [4, 5, 6], [7, 8, 9]] [[1, 2, 3], [4, 5, 6], [7, 8, 9]]

В приведенном выше выводе мы видим, что z является клоном x, который мы создали с помощью метода deecopy(). Если мы внесем изменения в один из дочерних объектов, это не повлияет на исходный объект.

Читайте также:  Создать странички на html

Оба объекта полностью независимы в глубокой копии. Список x был клонирован рекурсивно, включая все его дочерние объекты.

import copy x = [[1, 2, 3], [4, 5, 6], [7, 8, 9]] z = copy.deepcopy(x) x[2][2] = 'Hello' print(x)
import copy list1 = [0, [1, 2], [3,5], 4] # using deepcopy to deep copy list2 = copy.deepcopy(list1) # original elements of list print("The original list: ") for i in range(0,len(list1)): print(list1[i],end=" ") print("\r") # adding and element to new list list2[1][0] = 8 # Change is reflected in l2 print("The new list after deep copying: ") for i in range(0,len( list1)): print(list2[i],end=" ") print("\r") # Change is NOT reflected in original list # as it is a deep copy print("The original elements:") for i in range(0,len( list1)): print(list1[i],end=" ")
The original list: 0 [1, 2] [3, 5] 4 The new list after deep copying: 0 [8, 2] [3, 5] 4 The original elements: 0 [1, 2] [3, 5] 4

Копирование произвольных объектов Python

Мы также можем скопировать произвольные объекты Python, включая пользовательские классы, с помощью метода копирования. Методы copy.copy() и copy.deepcopy() могут использоваться для дублирования любых объектов.

Давайте разберемся в следующем примере.

import copy class Func_New: def __init__(self, x, y): self.x = x self.y = y def __repr__(self): return 'Func_new(%r, %r)' %(self.x, self.y) a = Func_New(50, 56) b = copy.copy(a) print(a) print(b) print(a is b) print(b is a)
Func_new(50, 56) Func_new(50, 56) False False

В приведенном выше коде мы создали класс определения пользователя с именем Func_new и определили __repr __() для проверки объектов. Затем мы создали мелкую копию с помощью модуля копирования. Мы создали экземпляр класса и сверили оригинал и его неглубокую копию.

Что следует помнить

Составные объекты – главное отличие мелкой копии от глубокой. Объекты, которые содержат другие объекты, такие как список или экземпляр класса, называются экземплярами списка или класса. Мы можем копировать произвольные объекты(включая пользовательские классы) с помощью модуля копирования.

Источник

Оцените статью