파이썬 pathlib 완전 정복 🧭 — 파일·디렉터리 경로를 우아하게 다루기
파이썬 pathlib 완전 정복 🧭
더 이상 os.path.join에 문자열 난무는 그만! pathlib.Path는
객체지향 경로 API로 읽기/쓰기, 탐색, 이동/삭제를 깔끔하고 안전하게 처리합니다.
1) Path 생성과 결합
from pathlib import Path
p = Path("data") / "images" / "cat.png" # '/' 연산자로 결합
print(p) # OS별 구분자로 출력
print(p.exists(), p.is_file(), p.is_dir())
home = Path.home()
cwd = Path.cwd()
print(home, cwd)
2) 파일 읽기/쓰기
from pathlib import Path
txt = Path("notes.txt")
txt.write_text("안녕하세요\npathlib 예제입니다.", encoding="utf-8") # 생성+쓰기
print(txt.read_text(encoding="utf-8")) # 읽기
binf = Path("logo.png")
data = binf.read_bytes() # 바이너리 읽기
Path("copy.png").write_bytes(data) # 바이너리 쓰기
대용량 파일은 open()으로 스트리밍하며 처리하세요.
3) 탐색: iterdir, glob, rglob
from pathlib import Path
root = Path("src")
# 1) 1단계 하위만
for child in root.iterdir():
print(child)
# 2) 패턴 매칭
for py in root.glob("*.py"): # 바로 아래에서만
print(py)
# 3) 재귀 탐색
for py in root.rglob("*.py"): # 하위 전체
print(py)
from pathlib import Path
p = Path("archive/2025/report.csv")
print(p.name) # 'report.csv'
print(p.stem) # 'report'
print(p.suffix) # '.csv'
print(p.suffixes) # ['.csv']
print(p.parent) # 'archive/2025'
print(p.parts) # ('archive','2025','report.csv')
# 이름/확장자 교체
print(p.with_name("summary.csv"))
print(p.with_suffix(".parquet"))
# 절대/해결
print(p.resolve()) # 심볼릭 링크·상대경로 해소
# print(p.relative_to("archive")) # '2025/report.csv'
5) 파일·디렉터리 조작
from pathlib import Path
# 디렉터리 만들기
out = Path("output/reports")
out.mkdir(parents=True, exist_ok=True)
# 이동/이름변경
src = Path("temp/data.csv")
dst = Path("output/data.csv")
src.replace(dst) # 같은 디스크면 거의 'mv'
# 안전 삭제
trash = Path("output/old.csv")
if trash.exists():
trash.unlink() # 파일만 삭제 (디렉터리는 rmdir)
# 디렉터리 전체 삭제는 shutil.rmtree(out) 사용
주의: unlink()는 파일만 삭제합니다. 디렉터리는 rmdir() 또는 shutil.rmtree()를 사용하세요.
6) 실전 레시피
6-1. 다운로드 폴더를 확장자별로 정리
from pathlib import Path
dl = Path.home() / "Downloads"
for f in dl.iterdir():
if f.is_file():
target = dl / f.suffix.lstrip(".").lower()
target.mkdir(exist_ok=True)
f.replace(target / f.name)
6-2. 프로젝트 전체 파이썬 파일 수와 총 크기
from pathlib import Path
root = Path(".")
files = list(root.rglob("*.py"))
total_size = sum(f.stat().st_size for f in files)
print(len(files), "files,", total_size, "bytes")
6-3. 날짜 prefix로 일괄 리네임
from pathlib import Path
from datetime import date
albums = Path("photos/album1")
prefix = date.today().strftime("%Y%m%d") + "_"
for f in albums.glob("*.jpg"):
f.replace(f.with_name(prefix + f.name))
7) 크로스플랫폼 팁
- 경로 결합은 항상
/ 연산자로: Path("a") / "b"
- 문자열로 출력이 필요하면
str(p) 또는 p.as_posix()
- Windows 예약 이름/NFC 정규화 등 특수 케이스는 OS별 차이가 있으니 테스트 권장
PurePath 계열은 파일 시스템 접근 없이 경로 계산만 할 때 사용
요약
pathlib.Path 하나로 경로 조작·입출력·탐색을 객체지향적으로 처리
glob/rglob으로 쉽고 빠른 패턴 탐색
with_suffix/with_name/replace로 안전한 이름 변경·이동
- 크로스플랫폼 이식성과 가독성 ↑
자주 묻는 질문(FAQ)
Q1. 문자열만 쓰던 코드와 함께 쓸 수 있나요?
A. 대부분의 표준 라이브러리가 Path를 직접 받거나 자동 변환합니다. 필요하면 str(Path(...))를 넘기세요.
Q2. 디렉터리 비우기/재귀 삭제는 어떻게 하나요?
A. pathlib 자체는 제공하지 않으므로 shutil.rmtree(Path(...))를 사용하세요.
Q3. 파일 잠금/동시성 제어가 필요한데요?
A. 플랫폼별 잠금은 별도 라이브러리를 사용하세요(filelock 등). pathlib는 경로 API에 집중합니다.
댓글
댓글 쓰기