본문 바로가기
언어별 개념 정리/Python

Python pathlib의 resolve와 absolute는 무엇이 다를까?

by char_lie 2026. 9. 19.
반응형

Python pathlib의 resolve와 absolute 경로 해석을 설명하는 썸네일

Python에서 상대 경로를 절대 경로로 바꾸려고 Path.absolute()와 Path.resolve()를 번갈아 쓰면 결과가 같아 보일 때가 많다. 하지만 두 메서드의 기준은 다르다. absolute()는 경로를 절대 형태로 만들고, resolve()는 심볼릭 링크와 상위 경로까지 실제 파일시스템 기준으로 해석한다.

파일이 존재하는지 검사해야 하는지도 선택에 영향을 준다. resolve(strict=True)는 경로가 없으면 예외를 내지만 기본값인 strict=False는 확인할 수 있는 부분까지만 해석한 뒤 나머지를 붙인다.

absolute는 절대 경로 형태만 만든다

현재 작업 디렉터리를 기준으로 상대 경로를 절대 형태로 바꾸려면 absolute()를 사용할 수 있다.

from pathlib import Path

path = Path("reports/../data.csv")

print(path)
print(path.absolute())

결과의 앞부분에는 현재 작업 디렉터리가 붙는다. 공식 문서에서 설명하는 핵심은 이 메서드가 정규화나 심볼릭 링크 해석을 하지 않는다는 점이다. 따라서 결과 문자열에 상위 경로가 남을 수 있다.

경로를 로그에 표시하거나 현재 위치를 붙인 형태가 필요할 때는 충분하다. 하지만 두 경로가 실제로 같은 파일을 가리키는지 비교하려는 목적이라면 문자열 형태만 절대 경로로 만드는 것으로 부족할 수 있다.

resolve는 링크와 상위 경로를 해석한다

resolve()는 경로를 절대 형태로 만들면서 상위 경로를 제거하고 가능한 범위에서 심볼릭 링크를 따라간다.

from pathlib import Path

path = Path("reports/../data.csv")

print(path.resolve())

reports/../data.csv는 정규화된 data.csv 경로로 바뀐다. 기본값은 strict=False이므로 마지막 파일이 없어도 가능한 부분까지 해석한 결과를 돌려준다.

경로 비교가 목적이라면 두 값을 모두 resolve()한 뒤 비교하는 방법을 사용할 수 있다.

from pathlib import Path

left = Path("cache/../data/output.csv")
right = Path("data/output.csv")

print(left.resolve() == right.resolve())

이 비교는 현재 작업 디렉터리와 파일시스템 상태를 사용한다. 대소문자 구분 방식이나 네트워크 파일시스템처럼 운영체제 환경의 차이도 고려해야 한다.

심볼릭 링크에서는 결과가 달라진다

임시 디렉터리 안에 실제 폴더와 그 폴더를 가리키는 링크를 만들면 차이를 확인할 수 있다.

from pathlib import Path
from tempfile import TemporaryDirectory

with TemporaryDirectory() as temp:
    root = Path(temp)
    real_dir = root / "real"
    real_dir.mkdir()
    target = real_dir / "sample.txt"
    target.write_text("pathlib", encoding="utf-8")

    link_dir = root / "shortcut"
    link_dir.symlink_to(real_dir, target_is_directory=True)

    linked_file = link_dir / "sample.txt"

    print(linked_file.absolute())
    print(linked_file.resolve())
    print(linked_file.resolve() == target.resolve())

absolute() 결과에는 shortcut 경로가 남고, resolve() 결과는 링크 대상인 real/sample.txt를 가리킨다. 마지막 비교는 True가 된다.

심볼릭 링크 생성 권한이나 지원 여부는 운영체제에 따라 다를 수 있다. 링크가 반드시 존재한다고 가정하는 테스트라면 지원 환경을 명시하거나 예외 처리를 추가한다.

strict 옵션으로 존재 여부까지 확인하기

배포 설정이나 입력 파일처럼 반드시 존재해야 하는 경로는 strict=True로 조기에 오류를 확인할 수 있다.

from pathlib import Path

config = Path("config/missing.toml")

try:
    resolved = config.resolve(strict=True)
except FileNotFoundError:
    print("설정 파일을 찾을 수 없습니다.")
else:
    print(resolved)

반대로 앞으로 만들 출력 파일의 경로라면 아직 파일이 없는 것이 정상이다. 이 경우 기본값인 strict=False를 사용하거나 부모 디렉터리만 별도로 확인한다.

from pathlib import Path

output = Path("build/reports/result.json").resolve()
output.parent.mkdir(parents=True, exist_ok=True)
output.write_text("{}", encoding="utf-8")

경로를 해석하는 일과 디렉터리를 생성하는 일은 별개다. resolve()를 호출했다고 해서 부모 폴더나 파일이 만들어지지는 않는다.

선택 기준 정리

현재 작업 디렉터리를 붙인 절대 경로 표현만 필요하면 absolute()를 사용할 수 있다. 상위 경로 정리와 심볼릭 링크 해석까지 필요하면 resolve()가 맞다. 입력 경로가 실제로 존재해야 한다면 resolve(strict=True)로 검증한다.

사용자 입력 경로를 보안 경계 안에 가두려는 경우에는 resolve() 한 번만으로 충분하다고 가정하지 않는다. 기준 디렉터리와의 포함 관계, 권한, 링크 변경 가능성을 함께 검토해야 한다. 메서드 이름보다 표시용인지, 실제 대상 비교인지, 존재 검증인지를 먼저 정하면 선택이 쉬워진다.

반응형

댓글