객체를 복사하시겠습니까? Python에서는 객체를 매개변수로 전달하든 함수 반환 값으로 전달하든 참조로 전달되기 때문입니다.
두 개의 숫자를 교환하는 C++ 함수를 살펴보겠습니다.
void swap(int &a, int &b) { int temp; temp = a; a = b; b = temp; }
이 예는 전달입니다. 참고 예시! 목적은 개념을 설명하는 것입니다. 참조로 전달한다는 것은 전달한 내용이 객체에 대한 참조이고 이 참조를 수정하면 원래 객체도 변경된다는 의미입니다. C/C++를 공부한 친구들은 두 숫자를 교환할 때 스왑 기능을 직접 구현하려면 해당 참조나 포인터를 전달해야 한다는 것을 모두 알고 있습니다.
Python은 참조 전달을 직접 사용합니다. 또 얼마나 편리하다고 불평하시겠습니까? 원본 개체를 변경하고 싶지 않은 상황에 대해 생각해 본 적이 있습니까? 그렇다면 여기를 보세요!
이제 l1이라는 목록이 있고 l1의 복사본이 필요하다고 가정합니다. l2 = l1과 같은 메서드를 직접 사용한 다음 l2를 일련의 수정하면 다음과 같습니다. l1을 직접 수정하는 것과 동일합니다. 이는 내가 원하는 것이 아닙니다! 예:
l1 = [1, 2] l2 = l1 l2.append(3) print l1 print l2 # l1 = [1, 2, 3], l2 = [1, 2, 3]
이는 Python 참조 전달로 인해 발생합니다. 즉, l1과 l2가 동일한 목록 객체에 속하므로 어떻게 할 수 있습니까? 우리는 다른 것을 얻습니다. 물체는 어디에 있습니까? 이렇게 여러 조각으로 뿌리는 게 쉽지 않나요? 예를 들어
l1 = [1, 2] l2 = l1[:] l2.append(3) # l1 = [1, 2], l2 = [1, 2, 3]
좀 더 복잡한 상황을 살펴보겠습니다.
l1 = [[1, 2], 3] l2 = l1[:] l2.append(4) # l1 = [[1, 2], 3], l2 = [[1, 2], 3, 4] l2[0].append(5) # l1 = [[1, 2, 5], 3], l2 = [[1, 2, 5], 3, 4]
아하, 뭔가 잘못된 것 같습니다. 이건 우리에게 필요한 것이 아닙니다! 무엇을 해야 할까요? 자, 오늘의 주제인 Python의 복사 모듈로 넘어가겠습니다!
복사본 가져오기
컨테이너 개체와 그 안에 포함된 모든 요소(요소의 하위 요소 포함)를 복사하려면 copy.deepcopy를 사용하세요. 이 방법은 시간과 시간이 많이 소요됩니다. 그러나 전체 복사본이 필요한 경우 이것이 유일한 방법입니다. 위에서 언급한 슬라이싱 방법은 복사 모듈의 복사 기능과 동일합니다.
위의 복사 작업이 너무 쉬워졌습니다.
l1 = [[1, 2], 3] l2 = copy.copy(l1) l3 = copy.deepcopy(l1) l2.append(4) l2[0].append(5) l3[0].append(6) # l1 = [[1, 2, 5], 3], l2 = [[1, 2, 5], 3, 4], l3 = [[1, 2, 6], 3]
관련 지침:
copy(x)
임의 Python 객체에 대한 얕은 복사 작업.
자세한 내용은 모듈의 __doc__ 문자열을 참조하세요.
deepcopy(x, memo=None, _nil=[])
임의 Python 객체에 대한 전체 복사 작업.
자세한 내용은 모듈의 __doc__ 문자열을 참조하세요.