Python으로 파일의 경로 및 목록 다루기

2020년 7월 3일 수정

이 글은 Python으로 파일 및 디렉토리의 경로(path)나 파일 목록 구하기와 관련된 내용을 정리한다. 딱히 이런 분류로 글을 쓰는 건 개인적으로 자주 사용하고 자주 찾게 되는 내용이라 그렇지 별 다른 구분이 있는 것은 아니다.

경로에서 파일명만 얻기

os.path 모듈의 basename() 함수를 사용하면 경로에서 파일명만 문자열로 따로 얻을 수 있다.

>>> import os
>>> os.path.basename('/foo/bar/test.txt')
'test.txt'

경로에서 디렉터리만 얻기

os.path 모듈의 dirname() 함수를 사용하면 해당 경로에서 디렉터리 부분만 문자열로 얻을 수 있다.

>>> import os
>>> os.path.dirname('/foo/bar/test.txt')
'/foo/bar'

파일명에서 확장자 분리하기

os.path 모듈의 splitext() 함수는 파일명에서 확장자를 분리하는 용도로 사용할 수 있다. 함수 이름에 주의하자.

>>> import os
>>> os.path.splitext('test.txt')
('test', '.txt')

splitext 는 파일명 뿐만이 아니라 경로(path)에서도 동작한다. 예를 들어 /foo/bar/text.txt 를 입력할 경우 /foo/bar/text.txt 로 분리된다.

경로에서 디렉터리와 파일 분리하기

이 경우에는 os.path 모듈의 split() 함수를 사용해보자.

>>> import os
>>> os.path.split('/foo/bar/sample.txt')
('/foo/bar', 'sample.txt')

참고로 os.path.split() 함수는 경로에서 마지막 요소만을 분리해주는 용도다. 그래서 상위 디렉터리를 구하는 용도로도 사용할 수 있다.

>>> os.path.split('/foo/bar')
('/foo', 'bar')

파일 혹은 디렉토리 구분하기

os.path 모듈에 isfile()isdir() 이라는 딱 적당한(?) 이름의 함수가 제공된다.

>>> import os
>>> os.path.isfile('/foo/bar/some/file.txt')
True
>>> os.path.isdir('/foo/bar/some/file.txt')
False

디렉터리 안의 파일 목록 얻기

여러 방법이 있겠지만 여기서는 os 모듈의 listdir 을 사용한 방법을 보자.

>>> import os
>>> os.listdir('.')
['foo.a', 'bar.b', 'somedir', ...]

디렉터리 안의 모든 파일 및 디렉터리 목록 얻기

특정 디렉터리 안의 내용물을 서브 디렉터리까지 다 포함해서 목록을 구할려면 여러 방법이 있겠지만 이번에는 Python 3.4 에서 추가된 pathlib 모듈의 Path 클래스의 rglob() 메서드를 이용해보자.

>>> from pathlib import Path
>>> list(Path("/foo/bar/dir").rglob("*"))
[PosixPath('/foo/bar/dir/a'), PosixPath('/foo/bar/dir/a/test.txt'), ...]

PosixPath 라는 새로운 타입이 등장하는데 이름처럼 경로를 표기하는데 적합한 타입이다. 이 타입은 별로 어려울 것 없이 str() 로 문자열로 변환이 되니 익숙한 방법을 사용하면 된다.

어쨌든 이런 식으로 해당 디렉터리 아래의 모든 파일과 디렉터리 목록을 1차원 리스트로 가공된 결과를 얻을 수 있다.

굳이 list() 를 이용해 리스트화를 한 이유는 결과를 바로 보기 위함이다. 보통 이런 경우 generator가 리턴된 것이기 때문에 굳이 list() 로 바로 풀어버릴 필요 없이 바로 for 루프를 돌면서 필요한 처리를 하는 게 성능과 메모리 효율이 더 좋을 것이다.

>>> for p in Path("/Users/seorenn/tmp/a").rglob("*"):
...     print(p)
...
/foo/bar/dir/a
/foo/bar/dir/a/test.txt
...

참고로 rglob() 의 파일 이름 패턴은 이 외의 다양한 패턴을 지원하므로 궁금하다면 매뉴얼을 찾아보자.