['',
'/Users/song-eun-u/anaconda3/bin',
'/Users/song-eun-u/anaconda3/lib/python36.zip',
'/Users/song-eun-u/anaconda3/lib/python3.6',
'/Users/song-eun-u/anaconda3/lib/python3.6/lib-dynload',
'/Users/song-eun-u/anaconda3/lib/python3.6/site-packages',
'/Users/song-eun-u/anaconda3/lib/python3.6/site-packages/aeosa',
'/Users/song-eun-u/anaconda3/lib/python3.6/site-packages/IPython/extensions',
'/Users/song-eun-u/.ipython']
📌️ 따라서 파이썬은 list의 각 경로를 하나 하나 확인하면서 해당 경로에 import 하고자 하는 package가 위치해 있는지 확인한다.
📌️ sys 는 파이썬에 포함되어 있는 모듈이다. 그러므로 다음 처럼 sys 모듈을 import 해서 sys.modules와 sys.path 를 출력할수도 있고 수정 할 수도 있다.
import sys
print(sys.path)
print(sys.modules)
📌️ 요약하면, 파이썬은 import 하고자 하는 모듈과 package를 찾을 때 먼저 sys.modules를 보고, 없으면 파이썬 built-in 모듈들을 확인하고 마지막으로 sys.path에 지정되어 있는 경로들을 확인해서 찾는다.
sys.path 에서도 못찾으면 ModuleNotFoundError 에러를 리턴한다.
sys.modules
built-in modules
sys.path
sys.modules는 built-in 모듈이기때문에 built-in에서 찾는다.
밑에 sys를 import하고 sys.modules를 프린트하면 bulit-in이라고 나온다.
absolute path는 프로젝트 내에서는 어느 파일, 어느 위치에서 import 하던지 경로가 항상 위와 같이 동일하다.
relative path는 프로젝트의 최상단 디렉토리를 기준으로 경로를 잡는게 아니라 import 하는 위치를 기준으로 경로를 정의한다.
현재 경로: package2의 module4
subpackage1의 module4의 func()함수를 import하려고하면
절대 경로
from package2.subpackage1.module5 import func()
상대 경로
from .subpackage1.module5 import func()
# absoulte path
#from calculator.add_and_multiply import add_and_multiply
# relative path
from .calculator.add_and_multiply import add_and_multiply
if __name__ == '__main__':
print(add_and_multiply(1,2))
from .multiplication import multiply
# from calculator.multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
def multiply(a,b):
return(a*b)
# absoulte path
# from calculator.add_and_multiply import add_and_multiply
# relative path
from .calculator.add_and_multiply import add_and_multiply
if __name__ == '__main__':
print(add_and_multiply(1,2))
>>> No module named '__main__.calculator'; '__main__' is not a package
메인모듈의 name 값은 relative path 일때는 파일명에 종속되고
absolute path일 때에 main 이 된다.
절대경로로 임포트해야 실행할 수 있다.
# absoulte path
from calculator.add_and_multiply import add_and_multiply
if __name__ == '__main__':
print(add_and_multiply(1,2))
>>> 5
from .multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
error => Attempted relative import in non-package
상대경로로 임포트 하면 main.py의 name이 파일명으로 바뀌어 에러가 발생한다.
from multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
절대경로로 임포트하면 main 모듈로 바뀌면서 main.py에 영향을 주지 않게 되어 실행이 된다.
init의 양옆에 언더바 2개씩이 있다. (velog에서 마크다운과 겹치기 때문에 편의상 언더바 없이 쓰겠다.)
양쪽에 언더바 2개를 가진 이름은 특별 취급을 받는다.
즉, 패키지를 import 할 때 가장 처음으로 실행되는 모듈이다.
또한 main.py 에서 절대 경로로 import 했던 add_and_multiply 모듈을 init.py 를 통하면 경로를 줄일 수 있고 Package에서 import 할 수 있는 변수/함수/클래스 제한하는 기능도 할 수 있다.