일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | |||
5 | 6 | 7 | 8 | 9 | 10 | 11 |
12 | 13 | 14 | 15 | 16 | 17 | 18 |
19 | 20 | 21 | 22 | 23 | 24 | 25 |
26 | 27 | 28 | 29 | 30 | 31 |
- 세그먼트 트리
- back propagation
- 다익스트라
- DP
- tensorflow
- dfs
- 너비 우선 탐색
- 알고리즘
- 가끔은_말로
- 문자열
- 이분 탐색
- 가끔은 말로
- 분할 정복
- 백트래킹
- 조합론
- pytorch
- 회고록
- object detection
- 크루스칼
- Overfitting
- 플로이드 와샬
- BFS
- c++
- 우선 순위 큐
- lazy propagation
- 자바스크립트
- 2023
- NEXT
- dropout
- 미래는_현재와_과거로
- Today
- Total
Doby's Lab
(os 모듈을 대체하는) pathlib 패키지 본문
최근에 다른 분들 코드 분석을 하면서 알게 된 패키지입니다. 일반적으로 파일을 불러오거나 같은 파일 시스템을 이용하기 위해서는 os 모듈을 사용했었는데 pathlib을 사용하는 케이스를 많이 봐서 전체보다는 주로 사용하는 기능들을 정리해보려 합니다. 그리고, pathlib은 파이썬 3.4 이상부터 지원이 됩니다.
1. 객체로 선언
pathlib 패키지에서 Path를 불러와서 아래와 같이 Path()에 파일 경로를 담아 파일 경로를 하나의 객체로 선언합니다.
from pathlib import Path
file_path = './from/to/here'
p = Path(file_path)
2. 문자열이 아닌 객체, os.path.join을 대체하는 연산자 '/'
우선, os와 다른 점은 파일에 대한 경로를 문자열이 아닌 객체로 다룬다는 것입니다.
이것에 대한 이점이 '연산자를 새롭게 정의를 할 수 있다는 것이다.'라고 나와있었지만, 아직은 '이게 왜?'라고 생각이 들지만 os.path.join() 대신 연산자 '/'를 사용할 수 있다는 점에서 편리한 거 같습니다.
dir_ = 'dir'
file_ = 'file'
# os
file = os.path.join(dir, file)
# pathlib
dir = Path(dir_)
file = dir / file_
3. 제일 자주 쓰이던 path.glob()
그리고, 디렉터리에서 많은 파일들을 탐색할 때 저는 주로 os.walk()를 사용했는데 path.glob()를 통해서 파일들을 찾아볼 수가 있었습니다. 또한, os.walk()를 사용할 때는 코드가 길어졌었는데 path.glob()를 통해 길이를 많이 단축시킬 수 있었습니다.
아래의 코드는 예전 프로젝트에서 데이터를 가져올 때, cat과 dog을 분리하기 위해서 여러 조건을 걸었던 코드입니다.
파일의 이름이(or 확장자가) 'jpg'로 끝이 나는지 첫 문자가 'c'인지 'd'인지를 구별하느라 코드가 꽤 지저분해 보입니다. 기발한 방법이
for dirname, _, filenames in os.walk(test_path):
for filename in filenames:
if(filename.endswith('jpg')):
if(filename[0] == 'c'):
test_target.append(0)
elif(filename[0] == 'd'):
test_target.append(1)
test_count = os.path.join(dirname, filename)
test_list.append(test_count)
하지만, path.glob()에서는 리눅스 와일드카드를 사용하여 파일 이름에 대한 패턴을 만든 후에 이 패턴에 해당하는 파일들을 모두 가져오는 방식을 사용합니다.
- * → 0개 이상의 모든 문자를 나타내는 특수문자
- ‘text’ → ‘text’라는 패턴에 해당하는지
- example : *.py → test.py, setup.py 등 이러한 패턴을 가진 파일들을 검출
- ** → 현재 디렉터리와 하위 디렉터리에서 모두 재귀적으로 검출하겠다는 뜻 보통 ‘**/~’ 이런식으로 사용하는 거 같다.
리눅스 와일드카드에서는 없는 추가적인 패턴 '**'이 존재합니다. 이 패턴은 '현재 디렉터리를 포함한 그 하위 모든 디렉터리를 전부 탐색하는 패턴'입니다. 그래서 꽤나 큰 디렉터리에서는 시간이 많이 소요될 수 있다는 단점이 공식 문서에 적혀있었습니다.
아래의 코드는 glob를 사용하여 train이라는 훈련용 데이터셋이 담긴 디렉터리에서 json 파일경로들을 모두 가져오도록 하여 리스트에 담는 코드입니다.
'train*.json'은 'train'으로 시작하고, '*'는 무수히 많은 번호가 있기 때문에 어떠한 문자가 와도 상관없으며, '.json'으로 끝나는 파일들을 의미합니다.
base_path = Path('a/b/c')
train_path = base_path / 'train'
train_json_li = list(base_path.glob('train*.json'))
이처럼 pathlib을 사용하면서 제일 편했던 건 glob를 사용함으로써 코드가 간결해지는 것이었습니다.
4. 서로 다른 운영체제에서의 충돌 방지
문서마다 제일 상단에서 얘기하지만 pathlib의 가장 큰 목적은 운영체제마다 파일을 다루는 시스템이 다르기 때문에 이를 충돌시키지 않기 위해서 나온 것이 pathlib이라는 설명이 되어있습니다.
아직은 팀 단위의 프로젝트 경험이 없기 때문에 필요성을 못 느끼는 말이기도 하지만 파일 시스템을 다룬다는 것이 이러한 점도 고려해야 하는구나 정도로 받아들였습니다.
마무리
이번엔 os 모듈을 대체하는 pathlib에 대해 알아보았습니다.
'/' 연산자와 glob가 현재로서는 제일 유용하게 쓰일 거 같아 2개만 정리해 보았는데 pathlib을 다루다가 '이건 필요하겠다' 싶은 기능들이 있다면 블로그에 추가적으로 정리를 해보겠습니다.
Reference
https://brownbears.tistory.com/415
https://docs.python.org/3/library/pathlib.html
https://www.freecodecamp.org/news/how-to-use-pathlib-module-in-python/
'Code about AI > Python' 카테고리의 다른 글
return self, 나를 왜 리턴 해야 할까? (Method Cascading) (0) | 2024.04.27 |
---|---|
상속을 할 때, super().__init__()을 하지 않는다면? (0) | 2023.11.11 |
Python의 Generator에 대하여 (2) | 2023.01.10 |
Python의 Iterator에 대하여 (0) | 2023.01.09 |
파이썬의 클래스(Class)에 대하여 (2) | 2022.12.08 |