sys.modules
sys.path
sys.modules
와 built-in modules
에 이어 마지막 순서로 확인하는 곳ModuleNotFoundError
에러를 리턴한다.sys
모듈을 불러올 수 있는 이유는?
파이썬이 sys
모듈을 통해 불러올 모듈과 packge를 찾는다는 걸 알아봤다. 그렇다면 sys
모듈 자체는 파이썬이 어떻게 찾을 수 있을까? 이를 이해하려면 sys
모듈이 위치한 경로를 알아야 한다. sys
모듈은 파이썬의 내장 모듈로, 모듈의 경로 정보는 파이썬 설치 시 default 값으로 저장된 상태다. 저장된 경로를 통해 파이썬은 sys
모듈을 찾아낸다.
# 'sys'모듈 이외의 파이썬 내장 모듈을 확인하고 싶다면... 아래의 메서드를 활용하자
import sys
print(sys.builtin_module_names)
Absolute path(절대 경로)
Relative path(상대 경로)
.
): import가 선언되는 파일의 현재 위치를 의미..
): 현재 위치에서 상위 경로로 이동main.py
는 main module에 해당하며, 패키지 폴더 calculator는 내부에 add_and_multiply.py
모듈과 multiplication.py
모듈을 갖고 있다. # main.py
# absoulte path
# from calculator.add_and_multiply import add_and_multiply
# relative path
from .calculator.add_and_multiply import multiplication
if __name__ == '__main__':
print(add_and_multiply(1,2))
# 결괏값: ImportError: attempted relative import with no known parent package
# add_and_multiply.py
from .multiplication import multiply
# from calculator.multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
# multiplication.py
# add_and_multiply.py
def multiply(a,b):
return(a*b)
main.py
는 calculator패키지의 모듈을 import해서 실행시키고 있지만, error로 인해 코드가 정상 처리되지 않고 있다. error의 발생 원인은 경로 설정과 관련 있는데, 자세한 이유는 python 공식 문서를 통해 짐작할 수 있다.Since the name of the main module is always "main", modules intended for use as the main module of a Python application must always use absolute imports.
__name__
== __main__
이 되면) 모듈의 이름이__main__
이 되면서 상대경로의 기준점이 바뀌게 된다.(relative import 시, 현재 모듈의 이름이 다렉토리의 기준이 되기 때문이다.) 경로의 기준점이 바뀌게 되면, 불러올 모듈을 제대로 찾을 수 없기 때문에 절대경로를 지정하여 경로의 기준점 변환에 상관없이 모듈을 import하도록 해야 한다. # main.py
# absoulte path
from calculator.add_and_multiply import add_and_multiply
# relative path
# from .calculator.add_and_multiply import multiplication
if __name__ == '__main__':
print(add_and_multiply(1,2))
# 결괏값: 5
if __name__ == '__main__':
은 무엇을 의미할까?
파이썬에서 모듈을 실행하는 방법엔 크게 두 가지가 있다. 하나는 인터프리터에서 직접 실행하는 것이고, 다른 방법은 실행할 모듈을 다른 모듈에서 import하여 실행하는 것이다.
직접 실행하는 경우
python3 add_and_multiply.py
다른 모듈에서 import하여 실행하는 경우
from calculator.add_and_multiply import add_and_multiply
add_and_multiply()
1번의 경우 모듈 add_and_multiply.py
의 __name__
이라는 변수에 __main__
할당된다. 반면 2번처럼 import하는 경우엔 __name__
변수에 모듈 이름인 add_and_multiply가 할당된다. 결국 if __name__ == '__main__':
의 의미는 모듈을 인터프리터로 직접 실행했을 경우에만 if문
내부의 코드를 실행하라는 의미이다.
from .multiplication import multiply
# from multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
# 결괏값: ImportError: attempted relative import with no known parent package
# from .multiplication import multiply
from multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
# 결괏값은 없지만, 함수가 정상적으로 실행됨
__init__
.py' 파일의 역할__init__.py
는 해당 디렉터리가 패키지로 인식되도록 도와주는 역할을 한다.
Import할 때 경로의 총 길이 줄여주는 역할을 한다.
__init__.py
를 활용해서 import할 수 있는 변수/함수/클래스를 제한할 수 있다.
# __init__.py
from .multiplication import multiply
__all__ = ['multiply']
# import 할 수 있는 함수를 multiply()로 제한
from calculator import *
add_and_multiply()
# multiply()
# 결괏값: NameError: name 'add_and_multiply' is not defined