Import Search 순서:
1. sys.modules
2. built-in modules
3. sys.path
sys.modules: 파이썬이 모듈이나package
를 찾기위해 가장 먼저 확인하는 곳
sys.modules
는 단순한dictionary
이다
이미import
된 모듈과package
들을 저장하고 있다
built-in modules: 파이썬에서 제공하는 파이썬 공식 라이브러리들
이미 파이썬에 포함되어 나오므로 파이썬이 쉽게 찾을 수 있다
sys.path: 모듈이나package
를 찾기위해 마지막으로 보는 장소
sys.path
는 기본적으로list
이며string
요소들을 가지고 있는list
다
각string
요소들은 경로를 나타낸다
sys.path
에서도 못찾으면ModuleNotFoundError
에러를 리턴한다
import sys print(sys) # <module 'sys' (built-in)>
sys 모듈:
built-in modules
( 파이썬에 포함되어 있는 모듈 )
직접 개발한
local package
를import
할때는 해당package
의 위치에 맞게import
경로를 선언해야 한다└── my_app ├── main.py ├── package1 │ ├── module1.py │ └── module2.py └── package2 ├── __init__.py ├── module3.py ├── module4.py └── subpackage1 └── module5.py
Absolute path:
import
를 하는 파일이나 경로에 상관없이 항상 경로가 동일 ( 프로젝트의 최상단 디렉토리를 기준 )
relative path:local package
안에서 다른local package
를import
할때 사용 (import
하는 위치를 기준 )
module5.py
의 위치를 절대경로로 표시 :my_app/package2/subpackage1/module5.py
(리눅스)
module4.py
의 위치를 절대경로로 표시 :my_app/package2/module4.py
(리눅스)
module5.py
의 위치에서module4.py
의 위치를 상대경로로 표시 :../module4.py
(리눅스)
에러
ImportError: attempted relative import with no known parent package
발생
이유는 무엇일까?
docs.python 을 참고하면 상대 임포트가 현재 모듈의 이름에 기반을 둔다는 것에 주의해야한다
메인 모듈의 이름은 항상"__main__"
이기 때문에, 파이썬 응용 프로그램의 메인 모듈로 사용될 목적의 모듈들은 반드시 절대 임포트를 사용해야 한다는 것이다
좀 더 설명을 해보면 메인 모듈은 항상 최상단에 위치해있기 때문에 상대경로를 사용 시no known parent package
알려진 상위 패키지가 없다고 뜨는 것이다
해결 방법은 절대경로를 사용하면 깔끔하게 해결 된다 !
multiply함수를 상대경로로 임포트
from .multiplication import multiply #from calculator.multiplication import multiply def add_and_multiply(a,b): return multiply(a,b) + (a+b)
# absoulte path from calculator.add_and_multiply import add_and_multiply , multiply if __name__ == '__main__': print(add_and_multiply(1,2)) print(multiply(1,2)) # 5 # 2
multiply함수를 절대경로로 임포트
#from .multiplication import multiply from calculator.multiplication import multiply def add_and_multiply(a,b): return multiply(a,b) + (a+b)
# absoulte path from calculator.add_and_multiply import add_and_multiply , multiply if __name__ == '__main__': print(add_and_multiply(1,2)) print(multiply(1,2)) # 5 # 2
두 방법 모두 main.py
에서 출력이 잘 되는 것을 확인 할 수 있다
메인모듈과 차이가 나는 이유는 add_and_multiply.py
는 패키지 안에 들어있는 모듈이기 때문이다
__init__.py
파일의 역할
__init__.py
는 해당 디렉토리가 패키지의 일부임을 알려준다
디렉토리의 모든 모듈을 불러 오고 싶을때*
을 사용하면 오류가 발생한다from calculator import * if __name__ == '__main__': print(add_and_multiply(1,2)) # NameError: name 'add_and_multiply' is not defined
이 때 사용하는 방법이
__init__.py
에서__all__ = [ ]
를 통해 디렉토리의 모듈을 넣어주면 된다# __init__.py __all__ = ['add_and_multiply'] # main.py from calculator import * if __name__ == '__main__': print(add_and_multiply.add_and_multiply(1, 2)) # 5
정상적으로 출력이 되는 것을 확인할 수 있