
Python copy.replace 사용법
copy.replace()는 기존 객체를 바꾸지 않고 일부 필드만 교체한 새 객체를 만들 때 쓰는 함수다. Python 공식 문서 기준으로 이 함수는 Python 3.13에서 추가됐다.
핵심은 세 가지다. copy.replace()는 새 객체를 만들지만 deepcopy() 같은 범용 복사 함수는 아니다. 지원 대상은 모든 객체가 아니라 namedtuple, dataclass, 그리고 __replace__()를 구현한 클래스처럼 제한적이다. 그래서 "불변 객체를 일부만 바꾼 새 값이 필요할 때" 가장 자연스럽다.
copy.replace는 언제 쓰면 될까?
기존 인스턴스를 직접 수정하면 안 되거나, 상태 일부만 바꾼 새 값을 안전하게 만들고 싶을 때 적합하다. Python 3.13 What's New 문서는 이 함수와 replace protocol이 특히 immutable object 작업을 더 단순하게 만든다고 설명한다.
- 설정 객체나 값 객체에서 한두 필드만 바꾼 새 인스턴스가 필요할 때
namedtuple._replace()와dataclasses.replace()를 타입마다 따로 외우고 싶지 않을 때- 사용자 정의 클래스에도 같은 패턴을 맞추고 싶을 때
반대로 임의의 리스트, 딕셔너리, 일반 클래스 인스턴스를 모두 처리하는 범용 복사가 목적이라면 copy.copy()나 copy.deepcopy() 쪽이 더 가깝다.
무엇을 보장하고 무엇을 보장하지 않을까?
공식 copy 문서는 copy.replace(obj, /, **changes)가 같은 타입의 새 객체를 만들고, 전달한 필드만 교체한다고 설명한다. 다만 같은 문서에서 이 함수는 copy()와 deepcopy()보다 더 제한적이라고 분명히 말한다.
| 항목 | copy.replace() |
copy.copy() / copy.deepcopy() |
|---|---|---|
| 주된 목적 | 일부 필드만 바꾼 새 객체 생성 | 객체 전체 복사 |
| 지원 범위 | 제한적 | 상대적으로 넓음 |
| 필드 이름 기반 변경 | 지원 | 직접 지원하지 않음 |
즉 replace는 "필드 교체 API"이고, copy와 deepcopy는 "복사 API"라고 구분하는 편이 정확하다.
어떤 객체에서 동작할까?
현재 Python 문서 기준으로 copy.replace()는 namedtuple()로 만든 named tuple, dataclass, 그리고 __replace__() 메서드를 정의한 클래스에서 동작한다. Python 3.13 What's New는 여기에 datetime.datetime, datetime.date, datetime.time, inspect.Signature, inspect.Parameter, types.SimpleNamespace, code object도 지원 목록으로 소개한다.
실무에서 기억할 기준은 단순하다. 기존에 각 타입이 제공하던 "필드 일부 바꿔 새 객체 만들기" 패턴을 copy.replace()가 공통 인터페이스로 묶어 준다고 보면 된다.
namedtuple과 dataclass에서는 어떻게 쓰면 될까?
named tuple은 원래 _replace() 메서드를, dataclass는 dataclasses.replace()를 제공한다. 공식 문서는 이 둘이 generic function인 copy.replace()로도 지원된다고 설명한다.
from collections import namedtuple
from dataclasses import dataclass
import copy
Point = namedtuple("Point", ["x", "y"])
p1 = Point(10, 20)
p2 = copy.replace(p1, x=30)
@dataclass(frozen=True)
class Config:
host: str
port: int
c1 = Config(host="127.0.0.1", port=5432)
c2 = copy.replace(c1, port=5433)
이 예시에서 원본 p1과 c1은 그대로 남고, 바뀐 값은 새 객체인 p2와 c2에만 반영된다. 불변 데이터 구조를 다룰 때 이 방식이 읽기 쉽다.
사용자 정의 클래스는 어떻게 지원할까?
copy 문서는 사용자 정의 클래스도 __replace__() 메서드를 정의하면 copy.replace()를 지원할 수 있다고 설명한다. 즉 표준 라이브러리가 정해 둔 프로토콜에 맞추면 호출부는 타입별 API를 따로 알 필요가 줄어든다.
import copy
class User:
def __init__(self, name, active):
self.name = name
self.active = active
def __replace__(self, /, **changes):
return User(
changes.get("name", self.name),
changes.get("active", self.active),
)
u1 = User("alice", True)
u2 = copy.replace(u1, active=False)
이 방식의 장점은 호출부를 통일할 수 있다는 점이다. 다만 어떤 키를 허용하고 잘못된 키를 어떻게 처리할지는 클래스 구현자가 책임져야 한다.
버전 기준은 어떻게 보면 될까?
copy.replace() 자체는 Python 3.13에서 추가됐다. 따라서 Python 3.12 이하를 함께 지원하는 코드라면 이 함수가 항상 있다고 가정하면 안 된다. 반대로 현재 최신 안정 문서인 Python 3.13.14와 Python 3.14.6 문서에는 이미 정식 API로 포함돼 있다.
버전 혼합 환경에서는 아래처럼 분기하는 편이 안전하다.
import copy
if hasattr(copy, "replace"):
new_obj = copy.replace(obj, name="next")
else:
# 타입별 기존 API 사용
new_obj = obj._replace(name="next")
실무 적용 기준
대부분의 경우 선택 기준은 세 가지면 충분하다.
- 필드 일부만 바꾼 새 객체가 필요하면
copy.replace()를 먼저 본다. - 임의의 객체를 넓게 복사해야 하면
copy.copy()또는copy.deepcopy()를 본다. - Python 3.12 이하 호환이 남아 있으면 버전 조건이나 대체 API를 같이 둔다.
정리하면 copy.replace()는 모든 복사를 위한 함수가 아니라, "필드 교체를 통한 새 객체 생성"을 공통화한 API다. named tuple, dataclass, 일부 표준 타입, 그리고 __replace__()를 구현한 사용자 정의 클래스에서 특히 깔끔하게 쓸 수 있다.
FAQ
copy.replace는 deepcopy의 축약형일까?
아니다. 공식 문서는 copy.replace()가 copy()와 deepcopy()보다 더 제한적이라고 설명한다. 목적도 전체 복사가 아니라 지정한 필드만 바꾼 새 객체 생성이다.
일반 dict나 list에도 바로 쓸 수 있을까?
공식 문서 기준으로 그렇지 않다. 이 함수는 named tuple, dataclass, 그리고 __replace__()를 구현한 클래스처럼 지원 대상이 정해져 있다.
Python 3.12에서도 사용할 수 있을까?
아니다. copy.replace()는 Python 3.13에서 추가됐다. Python 3.12 이하까지 지원해야 하면 타입별 기존 API나 버전 분기를 같이 준비해야 한다.
참고 자료
'프로그래밍 > C, C++, Java, Python' 카테고리의 다른 글
| Python argparse suggest_on_error 사용법 (0) | 2026.07.19 |
|---|---|
| Python Path.move 사용법 (0) | 2026.07.17 |
| Python Queue.shutdown 사용법 (0) | 2026.07.13 |
| Python functools.Placeholder 사용법 (0) | 2026.07.10 |
| Python weakref.finalize 사용법 (0) | 2026.07.08 |





