import는 어떻게 module과 package를 찾는가
1. sys.module과 sys.path 의 차이점
파이썬에서 모듈이나 패키지를 사용하기 위해선 해당 파일(모듈의 경우) 혹은 디렉토리(패키지의 경우) 가 어딨는지 파이썬이 찾을 수 있어야 import를 하여 사용할 수 있습니다. 이때 파이썬 정해진 순서에 따라 모듈 or 패키지를 찾습니다.
- sys.modules
- built-in modules
- sys.path
2. sys도 import 해야되는 모듈입니다. 파이썬은 sys 모듈의 위치를 어떻게 찾을 수 있을까요?
1 2 | import sys print(sys.modules) |
3. Absolute path와 relative path 차이점을 서술
-
파이썬의 built-in 모듈과 pip를 통해 설치한 외부 모듈 및 패키지는 일반적으로 import 하는데 큰 문제가 되지 않습니다.
Built-in 모듈은 당연히 잘 찾아지고, pip로 설치한 외부 모듈도 자동으로 site-packages 라는 디렉토리에 설치가 되는데, 이 site-packages는 sys.path에 이미 포함돼 있기때문에 찾는데 문제가 없습니다.
문제는 직접 개발한 local package입니다. 직접 개발한 local package를 import 할때는 해당 package의 위치에 맞게 import경로를 잘 선언해야 합니다
Local package를 import 하는 경로에는
- absolute path
- relative path
가 있습니다
-
absolute path
- 이름 그대로 절대 경로입니다
- import를 하는 파일이나 경로에 상관없이 항상 경로가 동일하기 때문
예를들어,
my_app이라는 프로젝트이며 package1과 package2 라는 2개의 package를 가지고 있습니다
그리고 package2는 subpackage1라는 중첩 package를 가지고 있습니다
Absolute path를 사용해 package1 과 package2를 import 하면 다음과 같습니다
from package1 import module1 from package1.module2 import function1 from package2 import class1 from package2.subpackage1.module5 import function2
경로들의 시작점이 전부 my_app 프로젝트의 가장 최상위 디렉토리에서 시작하는 것을 볼 수 있습니다
예를들어, subpackage1의 module5 모듈의 function2 함수를 import하려 거치는 경로는 아래와 같고,
my_app => package2 => subpackage1 => module5.py
이를 윈도우의 directory 형식으로 바꾸면
my_app\package2\subpackage1\module5.py
파이썬에서는 slash나 backslash(\)대신에 dot(.)을 사용해서 경로를 표현합니다
이미 my_app 프로젝트 안에 있으므로 my_app은 생략하고 경로를 표현하게 됩니다.
package2.subpackage1.module5.py
이걸 from import키워드를 사용해 import 하려면 어떻게 할까요??
from package2.subpackage1.module5 import function2
정리하자면, my_app 프로젝트 내에서는 어느 파일, 어느 위치에서 import 하던지 경로가 항상 위와 동일하게 되므로 absolute path라고 하는 것입니다
참고로 current directory 즉 현재의 프로젝트 디렉토리는 default로 sys.path에 포함합니다.
그러므로 absolute path 는 current directory부터 경로를 시작하게 되는 것입니다.
일반적으로 local pacakge를 import 할 때는 absolute path를 사용하면 됩니다.
그러나 경로가 길어질 수 있다는 단점이 있습니다.
-
relative path
경로가 길어지는 absolute path 의 단점을 보완하기 위해서 relative path를 사용합니다.
Relative path는 프로젝트의 최상단 디렉토리를 기준으로 경로를 잡는게 아니라. import하는 위치를 기준으로 경로를 정의합니다.
그래서 relative path는 local package안에서 다른 local package를 import 할 때 사용됩니다
예를들어 package2의 module3에서 package2의 class1과 package2의 하위 package인 subpackage1의 module5의 function2 함수를 import하려고 하면??
# package2/module3 from . import class1 from .subpackage1.module5 import function2
여기서 dot . 은 import가 선언되는 파일의 현재 위치를 이야기 합니다
현재 위치는 package2/module3.py 이므로, 현재 위치에서부터 원하는 모듈의 경로만 선언해주면 되는 것입니다
또한 dot2개를 사용할 수도 있습니다. dot 2개 .. 는 현재위치에서 상위 디렉토리로 가는 경로입니다
# subpackage1/module5.py from ..module4 import class4
Relative path는 선언해야 하는 경로의 길이를 줄여준다는 장점 은 있지만
헷갈리기 쉽고 파일 위치가 변경되면 경로 위치도 변경되어야 하는 단점 이 있기에
웬만한 경우 absolute path를 사용하는 것이 권장됩니다