# `copy` — 얕은 복사와 깊은 복사 연산

소스 코드: Lib/copy.py

파이썬에서 대입문은 객체를 복사하지 않고, 대상과 객체 사이에 바인딩을 만듭니다.가변(mutable) 컬렉션 또는 가변(mutable) 항목들을 포함한 컬렉션의 경우때로 컬렉션을 변경하지 않고 사본을 변경하기 위해 복사가 필요합니다.이 모듈은 일반적인 얕은 복사와 깊은 복사 연산을 제공합니다. (아래 설명 참고)

인터페이스 요약:

copy.copy(obj)

  obj의 얕은 사본을 반환합니다.

copy.deepcopy(obj[, memo])

  obj의 깊은 사본을 반환합니다.

copy.replace(obj, /, **changes)

  Creates a new object of the same type as obj, replacing fields with values from changes.

  Added in version 3.13.

exception copy.Error

  모듈 특정 에러의 경우 발생됩니다.

얕은 복사와 깊은 복사의 차이점은복합 객체(리스트 또는 클래스 인스턴스들과 같은 다른 객체를 포함한 객체)에만 유효합니다.

- 얕은 복사는 새로운 복합 객체를 만들고,(가능한 범위까지) 원본 객체를 가리키는 참조를 새로운 복합 객체에 삽입합니다.

- 깊은 복사는 새로운 복합 객체를 만들고,재귀적으로 원본 객체의 사본을 새로 만든 복합 객체에 삽입합니다.

깊은 복사 연산은 얕은 복사 연산에는 없는 두 가지 문제가 있습니다:

- 재귀 객체(직접적 또는 간접적으로 자신에 대한 참조를 포함하는 복합 객체)는 순환 루프의 원인이 될 수 있습니다.

- 깊은 복사는 모든 것을 복사하기 때문에, 지나치게 많이 복사할 수 있습니다. 가령, 복사본 간에 공유할 의도가 있는 것까지도.

`deepcopy()` 함수는 다음과 같은 방법으로 이 문제들을 피합니다:

- 현재 복사 패스 중에 이미 복사된 객체의 `memo` 딕셔너리를 가지고 있습니다; 그리고

- 사용자 정의 클래스가 복사 연산 또는 복사된 구성요소 집합을 재정의하도록 합니다.

이 모듈은 모듈, 메서드, 스택 트레이스, 스택 프레임, 파일, 소켓, 윈도우나 그 비슷한 유형들은 복사하지 않습니다. 원래 객체를 변화시키지 않고 반환함으로써 함수와 클래스를 (얕고 깊게) “복사” 합니다; 이것은 `pickle` 모듈로 처리되는 방식과 호환됩니다.

딕셔너리의 얕은 복사는 `dict.copy()`를 사용하여 복사할 수 있습니다.그리고 리스트의 얕은 복사는 예를 들어 `copied_list = original_list[:]` 처럼전체 리스트의 슬라이스를 대입하여 리스트를 복사할 수도 있습니다.

클래스는 피클링을 제어하기 위해 사용하는 것과 같은 인터페이스를 사용하여 복사를 제어할 수 있습니다.이러한 메서드들의 정보는 `pickle` 모듈 설명을 참고하세요.실제로 `copy` 모듈은 `copyreg` 모듈에 등록된 피클 함수를 사용합니다.

클래스가 자체적으로 복사 구현을 정의하기 위해선, `__copy__()` 와 `__deepcopy__()` 같은 특수 메서드를 정의할 수 있습니다.

object.__copy__(self)

  얕은 복사 연산을 실행하기 위해 호출됩니다; 추가적인 인자를 전달 하지 않습니다.

object.__deepcopy__(self, memo)

  깊은 복사 연산을 실행하기 위해 호출됩니다; memo 딕셔너리가 하나의 인자로 전달됩니다. `__deepcopy__` 구현에서 구성요소의 깊은 복사를 만들기 위해선, 구성요소를 첫 번째 인자로 하고 memo 딕셔너리를 두 번째 인자로 하여 `deepcopy()` 함수를 호출해야 합니다. memo 딕셔너리는 불투명 객체로 취급해야 합니다.

Function `copy.replace()` is more limited than `copy()` and `deepcopy()`, and only supports named tuples created by `namedtuple()`, `dataclasses`, and other classes which define method `__replace__()`.

object.__replace__(self, /, **changes)

  This method should create a new object of the same type, replacing fields with values from changes.

  Added in version 3.13.

더 보기

모듈 `pickle`

  객체 상태 조회와 복원을 지원하는데 사용되는 특수 메서드에 관한 논의