상대경로와 PyCharm 그리고 명령행
PyCharm에서 잘 작동하던 코드를 명령행에서 실행하려니 오류가 발생한다며 도움을 요청해 살펴보니 파일을 읽는 부분이다. 읽을 파일은 상대 경로로 지정하고 있다. 실례는 구조가 좀 복잡하지만 간단한 예로 문제를 생각해 보자.
프로젝트 구조는 다음과 같다.
가장 중요한 reader.py
부터 보자.
1 2 3 4 5 6 7 8 9 10 |
import os def reader(): path = 'config/hello.txt' print(os.path.join(os.getcwd(), path)) with open(path) as f: for line in f: print(line) |
파일을 읽는 간단한 함수이다. main.py
는 단순히 호출만 한다.
1 2 3 4 |
from modules.reader import reader reader() |
마지막으로 hello.txt
에는 읽을 내용이 있다.
1 |
Hello, World! |
PyCharm의 작업 디렉터리는 다음과 같다.
이 상태에서 실행한 결과는 다음과 같다.
경로도 올바르게 나오고 내용도 잘 읽어 출력한다. 이제 작업 디렉터리를 바꿔 보자.
실행결과는 다음과 같다.
경로가 맞지 않아 파일을 열지 못한다.
개발 환경 또는 배포 환경은 어떻게 바뀔지 모르므로 누가 어디에 두든 문제 없이 쓸 수 있게 하려면 상대 경로를 자연스레 생각하게 된다. 문제는 자신이 쓸 때는 문제가 없었는데 다른 개발자가 프로젝트에 포함해서 쓸 때는 문제가 생기거나, PyCharm에서는 문제가 없었는데 명령행에서 실행하니 안된다는 등의 문제가 생길 수 있다.
상대 경로를 사용하면 그 기준은 현재 작업 디렉터리가 된다. 이 점을 잘 모르고 일단 개발 환경에서 잘 작동하니 문제가 없다고 생각하기 쉽다. 그렇다면 상대 경로 이점을 이용하면서 문제 없이 만들 방법은 무엇일까.
1 2 3 4 5 6 7 8 9 10 11 |
import os def reader(): path = '../config/hello.txt' abs_path = os.path.join(os.path.abspath(os.path.dirname(__file__)), path) print(abs_path) with open(abs_path) as f: for line in f: print(line) |
os.path.dirname(__file__)
과 os.path.abspath()
를 이용해 상대 경로를 절대 경로로 바꾸면 된다. os.path.dirname(__file__)
를 호출하면 해당 파일이 속한 디렉터리를 알 수 있고 이를 상대 경로와 조합한다. 파이썬 3.4 이상부터는 pathlib.Path
를 쓸 수도 있다.
1 2 3 4 5 6 7 8 9 10 11 12 |
from pathlib import Path def reader(): path = '../config/hello.txt' abs_path = Path(__file__).parent.resolve().joinpath(path) print(abs_path) with open(abs_path) as f: for line in f: print(line) |
마지막 팁. 명령행에서 작업 디렉터리를 설정하려면 PYTHONPATH
환경 변수에 경로를 추가하면 된다.