파이썬을 학습하다 보면 대부분 dict는 익숙하게 사용합니다.
user = {
"name": "Tom",
"age": 20
}
하지만 조금 더 깊게 공부하다 보면 다음과 같은 코드를 만나게 됩니다.
from collections.abc import Mapping
그리고 이런 코드도 등장합니다.
class Config(Mapping):
...
처음에는 많은 사람들이 이런 의문을 가집니다.
“dict가 있는데 왜 Mapping을 또 사용하는가?”
이번 글에서는 dict와 Mapping의 차이점, 그리고 실무에서 왜 Mapping이 중요한지 초급부터 중급 수준까지 자세하게 설명해보겠습니다.
dict는 파이썬의 대표적인 자료구조입니다.
user = {
"name": "Tom",
"age": 20
}
이런 형태로 key-value 데이터를 저장합니다.
즉:
| key | value |
|---|---|
| "name" | "Tom" |
| "age" | 20 |
형태의 데이터를 저장하는 실제 객체입니다.
사용 방법도 매우 직관적입니다.
print(user["name"])
출력:
Tom
값 추가도 가능합니다.
user["city"] = "Seoul"
Mapping은 실제 데이터를 저장하는 자료구조가 아닙니다.
대신:
“dict처럼 동작하는 객체의 규칙(인터페이스)”
입니다.
즉 Mapping은:
라는 규칙을 정의합니다.
쉽게 말하면:
| 구분 | 의미 |
|---|---|
| dict | 실제 사전 |
| Mapping | 사전처럼 동작하는 규칙 |
입니다.
이 부분은 매우 중요합니다.
엔진이 있음
바퀴가 있음
실제로 움직임
핸들이 있어야 함
가속이 가능해야 함
브레이크가 있어야 함
즉:
dict는 완성품Mapping은 규격입니다.
다음은 가장 기본적인 Mapping 클래스입니다.
from collections.abc import Mapping
class Config(Mapping):
def __init__(self, data):
self._data = data
def __getitem__(self, key):
return self._data[key]
def __iter__(self):
return iter(self._data)
def __len__(self):
return len(self._data)
사용:
config = Config({
"host": "localhost",
"port": 3306
})
print(config["host"])
출력:
localhost
Mapping은 아래 3개 메서드만 구현하면 됩니다.
__getitem__
__iter__
__len__
이유는 Mapping이 나머지 기능을 자동 제공하기 때문입니다.
예를 들어 아래 코드가 모두 자동으로 동작합니다.
config.keys()
config.values()
config.items()
config.get("host")
"host" in config
이것이 파이썬 ABC(Abstract Base Class)의 강력한 특징입니다.
많은 기능이 비슷해 보이지만 핵심 차이는 다음입니다.
| 기능 | dict | Mapping |
|---|---|---|
| 실제 저장소 | O | X |
| 사용자 정의 가능 | 제한적 | 매우 자유로움 |
| 읽기 전용 | X | 기본 O |
| 내부 구현 변경 가능 | 제한적 | 매우 강력 |
다음 코드를 보겠습니다.
config["host"] = "127.0.0.1"
실행하면:
TypeError
가 발생합니다.
왜냐하면 Mapping은 기본적으로 읽기 전용 인터페이스이기 때문입니다.
즉:
__setitem__
이 구현되어 있지 않습니다.
반면 dict는 수정 가능합니다.
d = {"x": 1}
d["x"] = 100
이 부분이 가장 중요합니다.
실무에서는 단순 dict보다:
“dict처럼 보이지만 내부는 복잡한 객체”
가 훨씬 많이 사용됩니다.
예를 들어:
등입니다.
import os
from collections.abc import Mapping
class Env(Mapping):
def __getitem__(self, key):
return os.environ[key]
def __iter__(self):
return iter(os.environ)
def __len__(self):
return len(os.environ)
사용:
env = Env()
print(env["PATH"])
겉보기에는 dict처럼 사용합니다.
하지만 실제 데이터는 운영체제 환경변수입니다.
즉:
env["PATH"]
는 단순 dictionary 조회가 아니라 운영체제와 연결된 동작입니다.
이것이 Mapping의 진짜 힘입니다.
실무에서는 데이터가 매우 클 수 있습니다.
예를 들어 DB 조회를 생각해보겠습니다.
user["profile"]
를 호출할 때마다 실제 DB를 조회하도록 만들 수 있습니다.
즉:
dict처럼 보이지만
실제로는 DB와 연결
된 객체를 만들 수 있습니다.
파이썬에서는 객체가 Mapping 규칙을 만족하는지 검사할 수도 있습니다.
from collections.abc import Mapping
print(isinstance({}, Mapping))
출력:
True
왜냐하면 dict는 Mapping 인터페이스를 만족하기 때문입니다.
사용자 정의 클래스도 가능합니다.
config = Config({"x": 1})
print(isinstance(config, Mapping))
출력:
True
Mapping의 가장 중요한 철학은 이것입니다.
최소 구현 → 최대 기능 자동 제공
단 3개의 메서드만 구현하면:
등이 자동 생성됩니다.
이것이 파이썬의 ABC(Abstract Base Class) 설계 철학입니다.
예:
user = {"name": "Tom"}
예:
config["db_password"]
실제로는:
등을 수행할 수도 있습니다.
dict와 Mapping은 비슷해 보이지만 역할이 완전히 다릅니다.
실제 데이터를 저장하는 자료구조
dict처럼 동작하는 객체를 만들기 위한 인터페이스
실무에서는 단순한 데이터 저장보다:
“dict처럼 보이지만 내부는 복잡한 객체”
를 훨씬 많이 사용합니다.
그리고 바로 그때 Mapping이 강력한 힘을 발휘합니다.