파이썬 3.4 이상에 한하여 내장함수로 추가된 함수로 os 모듈보다 간편하게 사용할 수 있다는 장점때문에 이번에 설명드리고자 합니다. 해당 내장함수로 파일 위치, 입출력을 조금 더 빠르게 하실 수 있습니다. 더불어 해당 내용을 통해 OS에 관계없이 경로 설정이 간편해짐을 확인하실 수 있습니다.
한글 URL : python.flowdas.com/library/pathlib.html
영문 URL : docs.python.org/3/library/pathlib.html
pathlib에 대한 공식 설명 중
이 모듈은 다른 운영 체제에 적합한 의미 체계를 가진 파일 시스템 경로를 나타내는 클래스를 제공합니다. 경로 클래스는 I/O 없이 순수한 계산 연산을 제공하는 순수한 경로와 순수한 경로를 상속하지만, I/O 연산도 제공하는 구상 경로로 구분됩니다.
설명에서 확인할 수 있듯이 해당 내용은 파일 시스템 경로를 클래스로 제공합니다. 때문에 간편하죠. 해당 함수는 PurePath와 Path 2개로 구분하여 사용할 수 있습니다. 그러나 정확히는 Path는 PurePath를 상속받아 구현한 것이며 시스템 I/O 연산까지 수행이 가능하도록 구현되어 있습니다. 때문에 많은 경우 Path 하나만으로 대부분의 구현이 가능하다고 보시면 됩니다.
우선 디렉토리 혹은 파일이 존재하는지 확인하는 exist부터 보겠습니다.
import os
from pathlib import Path
dir_path = 'dataset/pixabay/p1'
# using os
if os.path.exists(dir_path):
print('exist check by os')
# using pathlib
q = Path(dir_path)
if q.exists():
print('exist check by pathlib')
해당 코드를 돌리면 모두 잘 작동하는 것을 확인할 수 있습니다. 파일에 대한 내용을 넣는다고 하더라도 exist에 대한 내용이 잘 적용됨을 볼 수 있습니다.
Path.is_dir() : 해당 명령어는 Path에 정의한 경로가 디렉토리인지를 확인하는 bool function입니다.
Path.is_file() : 해당 명령어는 Path에 정의한 경로가 파일인지를 확인하는 bool function입니다.
# True
print(q.is_dir())
# False
print(q.is_file())
Path.home() : 해당 명령어는 현재 위치한 곳의 home dir 경로를 반환해줍니다.
Path.cwd() : 해당 명령어는 현재 위치한 곳 경로를 반환해줍니다.
import os
from pathlib import Path
# C:\Users\aigong
print(Path.home())
# C:\Users\aigong\practice
print(Path.cwd())
Path.iterdir() : 해당 함수는 경로가 디렉토리일 때, 그 경로 내부의 바로 아래 서브 디렉토리만을 반환합니다.
dir_path = 'dataset/pixabay'
q = Path(dir_path)
for i in q.iterdir():
print(i)
"""
results :
dataset\pixabay\p1
dataset\pixabay\p2
dataset\pixabay\p3
"""
Path.glob() : 해당 함수는 특정 조건하에 있는 파일 또는 디렉토리를 가져올 때 많이 사용할 것 같습니다. 코딩은 해보신 분이라면 glob 패키지를 아실 것입니다. 아마 여기서 glob.glob()와 비슷한 효과를 낸다고 생각하면 편하실 것입니다.
# return current file and dir path
files = path.glob('*')
print(list(files))
# return all files and dir path including sub-files and sub-dir
files = path.glob('**/*')
print(list(files))
os를 활용하여 경로를 구성하고자 할 때는 항상 '/'를 써줘가며 경로를 일일이 join해야만 했습니다. 그러나 Path의 경우 '/'를 따로 str로 써주지 않아도 구분자로 사용되며 해당 방식을 통해 하위 디렉토리와의 합이 간편하게 설정될 수 있음을 알 수 있습니다.
dir_path = 'dataset'
# using os
f = os.path.join(dir_path + '/pixabay' + '/p1')
# dataset/pixabay/p1
print(f)
# using pathlib
q = Path(dir_path)
f = q / 'pixabay' / 'p1'
# dataset\pixabay\p1
print(f)
정확히는 PurePath.parents, PurePath.parts 이며 이를 상속받은 Path 역시 사용할 수 있었다고 보시면 됩니다. 단어에서 느껴지는 바와 같이 부모의 경로를 얻을 수 있는 parents 그리고 그 경로를 쪼갠 parts를 얻으실 수 있습니다.
path = Path.cwd()
# C:\Users\aigong\Desktop\code\practice
print(path)
# <WindowsPath.parents>
print(path.parents)
# [WindowsPath('C:/Users/aigong/Desktop/code'), WindowsPath('C:/Users/aigong/Desktop'),
# WindowsPath('C:/Users/aigong'), WindowsPath('C:/Users'), WindowsPath('C:/')]
print(list(path.parents))
# ('C:\\', 'Users', 'aigong', 'Desktop', 'code', 'practice')
print(path.parts)
Path.open() : 파일 열기
Path.read_text() : 파일 읽기
Path.write_text() : 파일 쓰기
# initially test.txt file must be exit in your dir
q = Path('test.txt')
t = q.open('r')
# <_io.TextIOWrapper name='test.txt' mode='r' encoding='cp949'>
print(t)
read = q.read_text()
# init write
print(read)
write = q.write_text('write the text\n')
# 15
print(write)
read = q.read_text()
# 'write the text'
print(read)
처음 test.txt 파일이 존재하고 그 안에는 'init write'라는 단어가 적혀있다고 가정해보겠습니다. 이 때 open을 하면 바로 읽을 수 있게되며 read_text()를 통해 그 안의 파일 내용을 읽을 수 있고 write_text()를 통해 글을 적을 수 있습니다. 다만 write는 덮어쓰기가 진행되니 유의하시길 바랍니다. 또한 그 안의 값을 읽고자 할 때는 다시 read_text()를 활용하시면 됩니다.