module일 경우에는 파이썬 파일, package의 경우 파이썬 파일들은 담고 있는 디렉토리들을 파이썬이 찾아야 import를 한다.
파이썬은 3가지 장소를 순서대로 보면서 찾는다.
sys.modules → built-in mudules → sys.path
파이썬이 module이나 package를 찾기위해 가장 먼저 확인하는 곳으로 단순한 dictionary이다. 그리고 이미 import된 module과 package들을 저장하고 있어서 한번 import된 module과 package들은 파이썬이 다시 찾지 않아도 되도록한다. 이말은 즉 새로 import하는 moduledms sys.modules에서 찾을수 없다.
파이썬에서 제공하는 파이썬 공식 라이브러리들이다. Built-in module들은 이미 파이썬에 포함되어 나오므로 파이썬이 쉽게 찾을 수 있다.
마지막으로 확인하는 장소가 sys.path이다. 기본적으로 list이며 string 요소들을 가지고 있는 list이다. 파이썬은 list의 각 경로를 하나하나 확인하면서 해당 경로에 import하고자 하는 package가 위치해 있는지 확인한다.
sys.path에서도 못찾으면 ModuleNotFoundError 에러를 리턴한다
파이썬의 built-in 모듈과 pip를 통해 설치한 외부 모듈 및 package는 일반적으로 import 하는데 큰 문제가 되지 않는다.
문제는 직접 개발한 local package이다. 직접 개발한 local package를 import할때는 해당 Package의 위치에 맞게 import경로를 잘 선언해야한다.
└── my_app
├── main.py
├── package1
│ ├── module1.py
│ └── module2.py
└── package2
├── __init__.py
├── module3.py
├── module4.py
└── subpackage1
└── module5.py
위의 프로젝트를 예로 들어보자.
package1
과 package2
를 import 하는 경우my_app
안의 최상위 디렉토리에서 시작한다. (이미 my_app
프로젝트 안에 있으므로 my_app
은 생략한다.)package2-module3
에서 package2-class1
과 package2-subpackage1-module5-function2
를 import하는 경우sys.modules
와 sys.path
의 차이점sys.modules은 단순한 dictionary이고 sys.path는 string요소들을 가지고 있는 list이다.
sys모듈을 파이썬에 포함된 모듈이기때문에 built-in modules에서 찾을 수 있다.
absolute path
와 relative path
의 차이점absolute path는 import를 하는 파일이나 경로에 상관없이 프로젝트의 최상단 디렉토리를 기준으로 경로를 잡고, relative path는 import하는 위치를 기준으로 경로를 정의한다.
다음과 같은 구조를가진 디렉토리와 파일들이 있다.
main.py에서 상대경로로 add_and_multiply를 import하게되면 다음과 같은 에러가 발생한다. 공식문서를 찾아보면 해답이 나와있다. 상대경로는 현재 모듈의 이름을 기반으로 import한다. 하지만 main module의 이름은 항상 __main__
이기 때문에 파이썬 어플리케이션의 main module로 쓰게되는 모듈은 항상 절대경로를 사용해야한다.
main모듈과는 다르게 add_and_multiply.py에서 multiply함수를 import할때는 절대경로와 상대경로 둘 다 사용가능하며 정상적으로 출력된다.
__init__.py
파일의 역할__init__.py
파일은 해당 디렉터리가 패키지의 일부임을 알려주는 역할을 한다.
⚠️ python3.3 버전부터는 __init__.py
파일이 없어도 패키지로 인식한다(PEP 420). 하지만 하위 버전 호환을 위해 __init__.py
파일을 생성하는 것이 안전하다.
Reference
https://docs.python.org/3/tutorial/modules.html#intra-package-references
https://www.python.org/dev/peps/pep-0420/
https://wikidocs.net/1418#9595init9595py