달나라 노트

Python Basic : PYTHONPATH (python module 설치 경로, python library 탐색 경로 추가하기, custom library import, sys.path) 본문

Python/Python Basic

Python Basic : PYTHONPATH (python module 설치 경로, python library 탐색 경로 추가하기, custom library import, sys.path)

CosmosProject 2021. 9. 16. 23:10
728x90
반응형

 

 

 

 

 

 

PYTHONPATH 환경변수에 대해 알기 전에 먼저 python library가 어떤 식으로 탐색되어 import되는지에 대한 기본적인 흐름을 천천히 살펴보고 갑시다.

 

 

 

 

Python을 사용하다보면 아래와 같이 module(library)을 설치하고 import하는 과정을 많이 거치게 됩니다.

 

 

pip install pandas
pip install os
conda install datetime

 

import pandas as pd
import os
from datetime import datetime

 

우리는 terminal에서 pip 구문을 이용해 여러 module들을 간단하게 설치하고 사용할 수 있죠.

 

근데 한가지 궁금한게 생겼습니다.

module을 설치한다고 했는데 그러면 이 module은 어디에 설치된걸까요?

 

 

 

 

import pandas

print(pandas.__file__)



-- Result
/Users/.conda/envs/lib/python3.8/site-packages/pandas/__init__.py

이에 대한 답은 위처럼 __file__ 속성을 이용하면 간단하게 알 수 있습니다.

pandas library의 __file__ 속성을 print 해보면 어떤 경로가 나오는 것을 알 수 있는데 이 경로가 바로 pandas가 설치된 경로란걸 알 수 있습니다.

 

 

Mac의 Finder를 열고 Command + Shift + g 단축키를 눌러 위 경로를 입력해봅시다.

 

그러면 아래처럼 실제로 pandas라는 directory가 있고, 이것이 우리가 import한 pandas library이며 이 안에 pandas의 모든 기능들이 들어있습니다.

 

 

 

 

 

import sample

print(sample.__file__)



-- Result
/Users/Documents/Code/sample.py

__file__속성은 단순히 설치된 library 뿐 아니라 custom module에도 사용할 수 있습니다.

 

위 예시는 제가 직접 sample.py라는 module을 작성한 후 별도의 python 파일(main.py)에서 sample.py를 module로써 import한 예시입니다.

 

참고로 sample.pymain.py는 동일한 경로(/Users/Documents/Code/)에 있습니다.

 

 

 

 

 

 

여기서 한 가지 더 의문점이 생깁니다.

pandas가 설치된 경로를 Python은 어떻게 알고 import를 했을까요?

 

library를 import하려면 해당 library가 설치된 경로를 알아야 합니다.

근데 우리는 위 예시에서 pandas나 sample이 설치된 경로를 python 코드에 적어주지 않았는데도 python은 module들의 import를 정상적으로 해내고 있습니다.

 

이것은 python의 기본적인 특징에서 알 수 있습니다.

 

Python code를 작성하고 이를 실행시키면 이 코드 자체가 바로 모든 기능을 수행하는 것이 아닙니다.

우리가 처음 Python을 설치할 때 Python interpreter라는 것이 설치되며 이 Python interpreter는 Python code를 기계어로 바꾸어 우리의 Python 코드를 컴퓨터가 인식할 수 있게 해주죠. (간단하게 이런식으로만 알고 넘어갑시다.)

 

근데 이 과정에서 Python interpreter는 python code에 어떤 다른 module을 import하는 부분이 있으면 기본적으로 정해진 경로를 찾아보게됩니다.

 

 

 

import sys

for dir in sys.path:
    print(dir)



-- Result
...
/Users/Documents/Code
/Users/Documents/Code
/Users/.conda/envs/lib/python38.zip
/Users/.conda/envs/lib/python3.8
/Users/.conda/envs/lib/python3.8/lib-dynload
/Users/.conda/envs/lib/python3.8/site-packages
...

Python interpreter가 import된 모듈을 찾기 위해 탐색하는 경로는 여러 가지가 있으며 sys library의 path 속성에 있는 경로를 찾아보게 됩니다.

보시면 여러 경로가 나오는데 거기서 ~~python3.8/site-packages라는 경로도 있습니다.

 

그리고 아래 코드에서 출력된 경로는 아까 pandas가 설치되었던 경로입니다.

import pandas

print(pandas.__file__)



-- Result
/Users/.conda/envs/lib/python3.8/site-packages/pandas/__init__.py

 

두 경로를 비교해봅시다.

 

sys.path에 있는 경로 중 하나

/Users/.conda/envs/lib/python3.8/site-packages

 

pandas가 설치된 경로

/Users/.conda/envs/lib/python3.8/site-packages/pandas/__init__.py

 

sys.path에 있는 경로 중 하나가 바로 pandas가 설치된 그 경로와 동일한 것을 알 수 있습니다.

 

 

따라서 pandas를 별도의 설정 없이 import할 수 있었던 것은 위처럼 기본적으로 Python interpreter가 내 컴퓨터에 존재하는 어떠한 경로들을 탐색해서 module이 있는지 없는지 찾아보기 때문인 것이죠.

 

 

 

 

import sample

print(sample.__file__)



-- Result
/Users/Documents/Code/sample.py

 

 

여기에 한 가지 더 추가하자면 위처럼 Python interpreter는 현재 실행된 python file이 존재하는 경로도 찾아보게됩니다.

 

main.py에서 sample.py를 import한다고 했습니다.

그리고 이 두 파일은 동일한 directory에 있다고 했죠.

따라서 python interpreter는 main.py를 실행했을 때 main.py가 있는 경로도 찾아봅니다.

그리고 main.py가 있는 곳에 sample.py도 있으니 제가 직접 만든 python file인 smaple.py를 바로 import할 수 있었던 것이죠.

 

 

 

 

 

 

 

위처럼 거의 대부분의 경우는 별도의 설정 없이 내가 원하는 module을 그냥 import 해주면 아무 문제없이 사용할 수 있습니다.

 

 

근데 문제가 발생합니다.

import sample

print(sample.__file__)



-- Result
module error

위 파일(main.py)을 직접 code editor에서 실행하는게 아니라,

terminal에서 python main.py라는 명령어를 입력하여 실행하면 module을 찾을 수 없다는 error가 발생할 수 있습니다.

 

특히 이런 경우가 custom library를 사용할 때 자주 발생하는데 이런 경우는 import된 module을 찾지 못했기 때문입니다.

 

위 예시는 단순히 sample.py가 main.py와 동일 경로에 있어서 실제로는 문제가 없을 수 있습니다.

하지만 보통 custom library를 관리할 때에는 custom library만 존재하는 directory를 따로 만들어 관리하는 경우가 많고,

이렇게되면 python interpreter가 바라보는 경로가 아닌 다른 경로에 custom library가 존재하게 되어 위처럼 모듈을 찾을 수 없다는 error가 발생할 수 있습니다.

 

 

이러한 문제를 해결하기 위해선 PYTHONPATH를 설정해주어야 합니다.

 

import sys

for dir in sys.path:
    print(dir)



-- Result
...
/Users/Documents/Code
/Users/Documents/Code
/Users/.conda/envs/lib/python38.zip
/Users/.conda/envs/lib/python3.8
/Users/.conda/envs/lib/python3.8/lib-dynload
/Users/.conda/envs/lib/python3.8/site-packages
...

PYTHONPATH는 환경변수의 일종입니다.

PYTHONPATH 환경변수에는 우리가 원하는 경로를 넣어줄 수 있으며

이 경로는 위에 예시에서 보이는 것 처럼 Python interpreter가 module을 찾게되는 기본 경로 뿐 아니라 추가로 module이 있을만한 곳을 알려준다고 생각하면 됩니다.

 

즉, "python interpreter에게 PYTHONPATH에 있는 모든 경로에 들어가서 module을 찾아봐" 라고 지시하는것이죠.

 

 

 

 

PYTHONPATH="/Users/Documents/custom_lib"

만약 위처럼 PYTHONPATH 환경변수를 설정해주면

Python interpreter는 기본 경로 외에 위 PYTHONPATH에 설정된 경로까지 들어가서 module을 찾게됩니다.

 

 

 

PYTHONPATH="/Users/Documents/custom_lib:/Users/Documents/Code/sub_lib"

PYTHONPATH에 여러 경로를 적어주고싶으면 콜론(:)으로 구분해서 적어주면 됩니다. 그리고 사이에 공백은 넣지 않는게 좋습니다.

 

 

 

 

즉, 위 같이 내가 만든 나만의 custom module이 있는 경로를 PYTHONPATH에 적어주면 Python interpreter는 custom module도 정상적으로 인식할 수 있게 되는것이죠.

 

 

 

 

- 추가

Mac에서 환경변수를 지정해주는 방법은 아래 포스팅 참고하시면 됩니다.

https://cosmosproject.tistory.com/269

 

 

 

- 추가

import sys

for dir in sys.path:
    print(dir)



-- Result
...
/Users/Documents/Code
/Users/Documents/Code
/Users/.conda/envs/lib/python38.zip
/Users/.conda/envs/lib/python3.8
/Users/.conda/envs/lib/python3.8/lib-dynload
/Users/.conda/envs/lib/python3.8/site-packages
...

아까 위에서 python interpreter가 기본적으로 module을 탐색하는 경로가 위와 같다고 했습니다.

 

 

 

 

/Users/.conda/envs/lib/python3.8

여기서 가장 기본이 되는 경로는 위 경로입니다.

 

그래서 저는 custom library를 만들 때 위 경로에 custom library 파일들을 담은 directory를 생성해두고,

해당 directory를 PYTHONPATH에 환경변수로 추가해줍니다.

 

그러면 컴퓨터의 다른 모든 경로에서 문제없이 custom library를 참조할 수 있게 됩니다.

 

환경변수 설정과 custom library 관리는 개인의 취향에 따르는 경우가 많으니 내용을 이해한 본인의 취향대로 관리하면 됩니다.

 

 

 

 

 

 

728x90
반응형
Comments