본문 바로가기
Study/Python

Python pathlib.Path로 경로관리하기

by 개발새-발 2021. 6. 10.
반응형

얼마전 노트북을 새로 구매하였다. 이전 노트북은 debian 운영체제를 사용하고 있었다. 그래서 개인적으로 간단하게 만드는 파이썬 프로그램들에는 별 생각 없이 슬래시(/)가 포함된 경로를 그대로 넣었었다. 이 프로그램들은 경로를 구분하는 데에 역슬래시를 사용하는 윈도우 프로그램에선 정상적으로 작동하지 않는다. os.path.join을 사용해서 처리하려다가 경로를 문자열이 아닌 객체로 처리하는 pathlib.Path에 대해 알게되었다.

 

Path를 이용해서 경로를 처리하는 법

import

from pathlib import Path

Path 객체 생성

p = Path('.')
p2 = Path('.','folder2')

시스템에 따라서 PosixPath, WindowsPath중 하나로 생성이 된다.

경로 연결하기

p1 = p / 'folder1'
p11 = p1.joinpath('folder11')
p11txt = p1 / 'folder11' / 'textfile.txt'

os.path.join 에서 처럼 운영체제 별로 경로 구분자를 달리 해서 경로가 생성이 된다. 아래 코드에서 결과를 보자. windows에서 실행한 결과이다.

print(p,p2,p1,p11,p11txt,sep='\n')
.
folder2
folder1
folder1\folder11
folder1\folder11\textfile.txt

 

경로에 폴더, 파일 존재여부 확인 exists()

print(p11txt.exists())
print((p11 / 'blabla').exists())
True
False

 

Path 객체를 문자열로 바꾸기

경로를 받는 여러 함수 중, 문자열이 아니면 처리를 하지 못하는 함수들이 존재한다. 이때, Path객체를 문자열로 바꾸어 주어야 한다. 그저 str로 형변환만 해주면 된다.

spath = str(p11txt)
print(spath,type(spath))
folder1\folder11\textfile.txt <class 'str'>

 

상대경로를 절대경로로 변경하기 resolve()

절대경로가 필요한 경우가 있다. resolve()를 호출하면 절대경로로 변환된 Path객체가 생성된다.

abspath = p11txt.resolve()
print(abspath,type(abspath),sep='\n')
C:\Users\Username\parentpath\folder1\folder11\textfile.txt
<class 'pathlib.WindowsPath'>

 

경로에서 이름, 확장자, 확장자를 제외한 이름 가져오기 name, suffix, stem

각 정보를 문자열로 받을 수 있다.

print(p11txt,
      p11txt.name,
      p11txt.suffix,
      p11txt.stem,
sep='\n')
folder1\folder11\textfile.txt
textfile.txt
.txt
textfile

 

부모경로 불러오기 parent

부모경로를 Path객체로 받는다.

print(p11txt,
      p11txt.parent,
      p11,
      p11.parent,
sep='\n')
folder1\folder11\textfile.txt
folder1\folder11
folder1\folder11
folder1

 

폴더 탐색 iterdir(), glob()

iterdir()Path객체가 가리키는 폴더의 내용들을 볼 수 있다. 이때, 우리는 그 폴더내의 디렉토리 혹은 파일의 Path객체들을 받는다.

for child in p.iterdir():
    print(child,type(child))
.ipynb_checkpoints <class 'pathlib.WindowsPath'>
folder1 <class 'pathlib.WindowsPath'>
folder2 <class 'pathlib.WindowsPath'>
libpath.ipynb <class 'pathlib.WindowsPath'>

glob()을 사용할 수도 있다.

for child in p.glob('**/*'):
    print(child,type(child))
.ipynb_checkpoints <class 'pathlib.WindowsPath'>
folder1 <class 'pathlib.WindowsPath'>
folder2 <class 'pathlib.WindowsPath'>
libpath.ipynb <class 'pathlib.WindowsPath'>
.ipynb_checkpoints\libpath-checkpoint.ipynb <class 'pathlib.WindowsPath'>
folder1\folder11 <class 'pathlib.WindowsPath'>
folder1\text1.txt <class 'pathlib.WindowsPath'>
folder1\text2.txt <class 'pathlib.WindowsPath'>
folder1\text3.txt <class 'pathlib.WindowsPath'>
folder1\folder11\textfile.txt <class 'pathlib.WindowsPath'>

 

Path를 이용하여 경로의 파일 혹은 폴더를 조작하는 방법

Path객체를 이용하여 그 객체가 가리키는 폴더나 파일에 조작을 가할 수 있다. 지우고, 생성하고, 이름을 바꾸고, 파일을 작성하는 등의 작업들이 가능하다.

 

파일 생성, 제거 touch() , unlink()

touch() 사용시에 동일한 경로의 파일이 있는 경우 오류를 발생하지만, exist_ok=True로 실행했을 경우 오류는 무시된다. unlink()사용시 symbolic 링크인 경우 링크가 끊어진다. 제거하고자 하는 파일이 이미 없는 경우 오류를 발생하지만 missing_ok=True인 경우 (python 버전 3.8 이상)  오류는 무시된다.

pnewfile = p11 / 'newtext.txt'

print("Before touch : ",pnewfile.exists())
pnewfile.touch()
print("After touch : ",pnewfile.exists())
pnewfile.unlink()
print("After unlink ",pnewfile.exists())
Before touch :  False
After touch :  True
After unlink  False

 

폴더 생성 제거 mkdir(), rmdir()

mkdir()에도 touch()처럼 exist_ok를 지정해 줄 수 있고, 그 내용은 같다. parent=True인 경우 주어진 경로의 부모경로들이 존재하지 않은경우 그 경로들을 생성하나 false인 경우 오류를 발생한다. rmdir()은 빈 폴더만 제거해 준다.

pnewfolder = p11 / 'newfolder'

print("Before mkdir : ",pnewfolder.exists())
pnewfolder.mkdir()
print("After mkdir : ",pnewfolder.exists())
pnewfolder.rmdir()
print("After mkdir : ",pnewfolder.exists())
Before mkdir :  False
After mkdir :  True
After mkdir :  False

 

파일 조작 open()

파이썬 기본 open()과 동작이 같다. 단지 경로만 open에 따로 입력해줄 필요 없을 뿐이다.

file = p11txt.open('w')
file.write('hello world')
file.close()

with p11txt.open('r') as file:
    print(file.readline())
hello world

 

파일조작 read_text(), write_text()

open, close를 우리가 직접 해줄 필요가 없다. read_text(), write_text()가 시작될 때 open되고, 끝나면 close된다. 내부 구현을 보면 with문과 함께 open되는 것을 볼 수 있다.

p11txt.write_text('hello')
print(p11txt.read_text())
hello

 

파일조작 read_bytes(), write_bytes()

read_text(), write_text()와 거의 같다. byte object로 읽고 쓸 뿐이다.

p11txt.write_bytes(b'hello byte')
print(p11txt.read_bytes())
b'hello byte'

 

이외에도 더 많은 기능들이 있다. 나머지 기능들은 https://docs.python.org/3/library/pathlib.html 여기서 참고하자.

 

 

반응형

댓글