pathlib (3.4+) 가 모든 path 연산용 메서드 가진 Path 객체 줘. os.path 는 문자열 받는 함수, pathlib 은 객체의 메서드. 차이 중요한 이유 — path 객체가 깔끔히 합성 (p / "sub" / "file.txt") + 영어처럼 읽혀 (p.exists(), p.is_dir(), p.glob("*.py")).
Path 가 메인 클래스 — 그리고 똑똑해
Path("some/path") 호출하면 OS 따라 PosixPath 또는 WindowsPath 인스턴스 반환. 둘 다 같은 API 공유. / 연산자가 trailing/leading 슬래시 무관하게 path 합쳐. Path.home() 과 Path.cwd() 가 자주 쓸 단축.
Query 메서드
os.path 통해 할 모든 체크가 Path 등가물 — .exists(), .is_file(), .is_dir(), .is_symlink(). 다 bool 반환. .stat() 가 시스템 stat 정보 반환. .suffix, .stem, .name, .parent, .parts 가 문자열 조작 없이 path 분해.
읽기/쓰기 — 편의 메서드
p.read_text(encoding='utf-8') 가 열고 읽고 닫음. p.write_text(content, encoding='utf-8') 가 열고 쓰고 닫음. 바이너리엔 p.read_bytes() / p.write_bytes(). 4 줄짜리 with open() 블록 짤 작은 파일에 완벽.
Globbing — 패턴으로 파일 찾기
p.glob("*.py") 가 p 안 모든 Python 파일 반환. p.rglob("*.py") 가 재귀. 둘 다 Path 객체 iterator 반환. 패턴 문법 — * 어떤 글자, ** 어떤 디렉토리, ? 한 글자, [abc] 글자 클래스.
Pythonic Way: 새 코드엔 pathlib 디폴트. os.path 는 *해야만* 할 때만 — 많은 옛 라이브러리 + API 가 문자열 받음, str(Path(...)) 가 다리. 절반만 가지 마 — path 레이어엔 pathlib 골라서 일관되게 박아.
Code
Path 기본 — 생성과 / 연산자·python
from pathlib import Path
# 생성
p = Path("/Users/you_username")
print(p) # /Users/you_username
# 합치기 — / 연산자
file_path = p / "Documents" / "notes.txt"
print(file_path) # /Users/you_username/Documents/notes.txt
# 유용한 시작점
print(Path.home()) # /Users/you_username
print(Path.cwd()) # 현재 작업 디렉토리
print(Path(".").resolve()) # 현재 dir, 절대 경로
from pathlib import Path
p = Path("/etc/hostname")
print(p.exists()) # True
print(p.is_file()) # True
print(p.is_dir()) # False
# 분해
q = Path("/etc/profile.d/00-aliases.sh")
print(q.name) # '00-aliases.sh'
print(q.stem) # '00-aliases' — suffix 없는 이름
print(q.suffix) # '.sh'
print(q.parent) # PosixPath('/etc/profile.d')
print(q.parts) # ('/', 'etc', 'profile.d', '00-aliases.sh')
# Stat
import time
stat = p.stat()
print("크기:", stat.st_size)
print("수정:", time.ctime(stat.st_mtime))
read_text / write_text — 단축·python
from pathlib import Path
p = Path("/tmp/note.txt")
# 쓰기
p.write_text("hello pippa\n", encoding="utf-8")
# 읽기
content = p.read_text(encoding="utf-8")
print(content)
# 바이트
b = Path("/tmp/raw.bin")
b.write_bytes(b"\xDE\xAD\xBE\xEF")
print(b.read_bytes()) # b'\xde\xad\xbe\xef'
glob + rglob — 패턴 매칭·python
from pathlib import Path
# 디렉토리의 모든 .py (비재귀)
for py in Path(".").glob("*.py"):
print(py)
# 재귀 — cwd 아래 모든 .py
for py in Path(".").rglob("*.py"):
print(py)
# 패턴 변형
# * 어떤 글자 (no /)
# ** 어떤 디렉토리 (rglob 와)
# ? 한 글자
# [abc] a, b, c 중 하나
# count / sort 원하면 list()
files = sorted(Path(".").glob("*.txt"))
print(f"{len(files)} 파일")
흔한 연산 — mkdir / rename / unlink·python
from pathlib import Path
# 디렉토리 생성 (parents=True 가 중간 만듦, exist_ok 가 에러 억제)
d = Path("/tmp/nested/dir")
d.mkdir(parents=True, exist_ok=True)
print(d.exists()) # True
# 안에 파일
(d / "child.txt").write_text("hi", encoding="utf-8")
# rename
original = d / "child.txt"
renamed = original.rename(d / "renamed.txt")
print(renamed) # /tmp/nested/dir/renamed.txt
# 파일 삭제
renamed.unlink(missing_ok=True)
print(renamed.exists()) # False
# 빈 디렉토리 제거
d.rmdir() # 안 비면 raise
# 비어있지 않은 트리엔 — shutil.rmtree(d)
pathlib 사용 — (a) /tmp/quest_dir 디렉토리 없으면 생성. (b) 안에 다른 내용으로 세 텍스트 파일 (a.txt, b.txt, c.txt) 쓰기. (c) glob('*.txt') 로 순회, 이름 + 파일 크기 출력. (d) /tmp 에서 rglob 로 세 파일 발견 확인. (e) 정리 — 세 파일 + 디렉토리 삭제.
Progress
Progress is local-only — sign in to sync across devices.