sys.modules built-in modules sys.path
sys.modules ~ sys.path의 순서대로 모듈과 패키지를 검색한다.
파이썬이 모듈이나 package를 찾기위해 가장 먼저 확인하는 곳으로
sys.modules
는 단순한 dictionary다. 그리고 이미 import된 모듈과 package들을 저장하고 있다.
즉, 한번 import된 모듈과 package들은 파이썬이 또 다시 찾지 않아도 되도록 하는 기능을 가지고 있다.
그러므로 새로 import 하는 모듈은 sys.modules
에서 찾을 수 없다.
파이썬에서 제공하는 공식 라이브러리
이미 파이썬에 포함되어있어 찾기가 쉽다.
sys.path는 기본적으로 list이며 string 요소들을 가지고 있는 list이다.
sys를 import하여 출력해보면 아래와 같이 list 형태로 path가 담겨있는 것을 알 수 있다.
import sys
print(sys.path)
['', '/home/mingu', '/usr/bin', '/usr/lib/python39.zip', '/usr/lib/python3.9', '/usr/lib/python3.9/lib-dynload', '/home/mingu/.local/lib/python3.9/site-packages', '/usr/local/lib/python3.9/dist-packages', '/usr/lib/python3/dist-packages']
즉 파이썬은 module과 package를 import 할 때 dictionary로 이루어진 sys.module안에 있는지 찾고 없으면 파이썬에 built-in된 모듈들을 확인한 후 마지막으로 list로 이루어진 sys.path에서 찾는다.
어느 곳에도 없으면 에러 ModuleNotFoundError
를 리턴한다.
sys(System-specific parameters and functions) 공식 문서 를 살펴보면 sys란 인터프리터에 의해서 사용되거나 관리되는 변수와 함수에 대한 접근을 항상 제공하는 모듈이라고 설명하고 있다. 우리는 import 를 통해 사용하고 싶은 모듈과 패키지를 손 쉽게 사용할 수 있다.
sys.path는 모듈과 패키지의 검색경로 및 순서를 바꿀 수 있다.(그래서 list형식으로 되어있나보다.)
sys.modules는 path와 달리 딕셔너리 형으로 되어있으며 순서를 바꿀 수 없다(dict엔 순서가 없어서 인듯하다.)
sys는 파이썬에 포함되어 있는 모듈이다.
즉 built-in 되어 있기에 앞서 설명한 sys.modules에서 없으면 built-in에서 발견할 것이다.
파이썬의 built-in 모듈과 pip
을 통해 설치한 외부 모듈 및 package는 일반적으로 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
├── main.py
├── package1
│ ├── module1.py
│ └── module2.py
└── package2
├── __init__.py
├── module3.py
├── module4.py
└── subpackage1
└── module5.py
my_app
이라는 프로젝트 이며 package1
과 package2
라는 2개의 package를 가지고 있다.
그리고 package2
는 subpackage2
라는 중첩 package를 가지고 있다.
Absolute path를 사용하여 package1과 2를 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
이걸 from import 키워드를 사용해 import 하게 되면 다음 처럼 나타낼 수 있다.
from package2.subpackage1.module5 import function2
어느 위치에서 import 하던지 경로가 항상 위와 같이 동일하게 되므로 absolute path 라고 한다
일반적으로 local package를 import 할때는 absolute path를 사용하면 된다.
다만 absolute path를 사용하게 되면 한가지 단점이 있는데 바로 경로가 길어질 수 있다.
그래서 이러한 단점을 보완하기 위해서 relative path를 사용할 수 있다.
하지만 relative path는 헷갈리기 쉽고 파일 위치가 변경되면 경로도 같이 변경되어야 하는 단점 때문에 absolute path 사용이 권장된다.