sys.modules 와 sys.path의 차이점을 서술해 주세요.
sys.modules
파이썬이 모듈이나 package를 찾기위해 가장 먼저 확인하는 곳입니다.
sys.modules는 단순한 dictionary 입니다.
그리고 이미 import된 모듈과 package들을 저장하고 있습니다.
한번 import된 모듈과 package들은 파이썬이 또 다시 찾지 않아도 되도록 하는 기능을 가지고 있습니다.
새로 import 하는 모듈은 sys.modules 에서 찾을 수 없습니다.
sys.path
마지막으로 보는 장소가 바로 sys.path 입니다.
sys.path는 기본적으로 list이며 string 요소들을 가지고 있는 list 입니다.
sys 도 import 해야하는 모듈입니다. 파이썬은 sys 모듈의 위치를 어떻게 찾을 수 있을까요?
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 에러를 리턴합니다.
Absolute path와 relative path의 차이점을 서술해 주세요.
Absolute path는 이름 그대로 절대 경로 입니다. 왜 절대 경로인가 하니, import를 하는 파일이나 경로에 상관없이 항상 경로가 동일하기 때문입니다.
absolute path는 current directory 로 부터 경로를 시작하게 되는것입니다.
일반적으로 local package를 import 할때는 absolute path를 사용하면 됩니다.
relative path
absolute path를 사용하게 되면 한가지 단점이 있는데 바로 경로가 길어질 수 있다는 점입니다. 그래서 이러한 단점을 보완하기 위해서 relative path를 사용할 수 있습니다.
Relative path 는 absolute path와 다르게 프로젝트의 최상단 디렉토리를 기준으로 경로를 잡는게 아니라 import 하는 위치를 기준으로 경로를 정의합니다. 그래서 일반적으로 relative path는 local package 안에서 다른 local package를 import 할때 사용됩니다.
Relative path는 선언해야 하는 경로의 길이를 줄여준다는 장점은 있지만 헷갈리기 쉽고 파일 위치가 변경되면 경로 위치도 변경되어야 하는 단점이 있습니다.
그러므로 웬만한 경우 absolute path를 사용하는게 권장 됩니다.
calculator 패키지 만들기
main.py
from .calculator.add_and_multiply import add_and_multiply
if __name__ == '__main__':
print(add_and_multiply(1,2))
add_and_multiply.py
from .multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
multiplication.py
def multiply(a,b):
return(a*b)
실행화면
코드를 그대로 실행하게 되면, 이미지의 에러가 발생하는걸 확인 할 수 있다.
ImportError: attempted relative import with no known parent package
에러의 원인을 찾아보았다.
패키지 안에서 스크립트 파일(실행 파일)을 실행 시키려고 했을 때 발생하는 에러이다. 일단 이유는 파이썬의 인터프리터가 main 의 위치를 알지 못하기 때문에 위 같은 에러가 발생하는 것이다. 파이썬의 인터프리터는 relative import의 모듈 위치를 정할 때(기준이 되는 위치) name 속성에 의해 결정되고
터미널에서 파이썬을 직접 실행시키면 name == 'main'이 되기 때문이다.
출처: https://ebbnflow.tistory.com/320 [삶은 확률의 구름:티스토리]
원인을 보니 Relative import 경로를 설정한 것이 문제인것 같아, Absolute import로 경로를 바꾸어 설정해보기로 했다.
정상실행되어 5가 출력되는걸 확인할 수 있다.
add_and_multiply.py에서 multiply함수를 절대경로와 상대경로도 각각 임포트 해보고 main 모듈과 차이점을 생각해보고 결과를 출력해 보세요
add_and_multiply은 Relative import, Absolute import 상관없이 둘다 정상 실행된다. 이유는 add_and_multiply는 기본 모듈이 아니기 때문이다. 기본 모듈인 main만 Absolute import로 불러와야 하며, 기본 모듈이 아닌 모듈은 어떻게 불러와도 실행하는데는 상관이 없다.
init.py 파일의 역할에 대해서도 정리해서 블로깅 해주세요.
init.py 파일에는 아무코드도 없지만 init 파일은 해당 디렉토리가 패키지임을 알려주는 역할을 한다. 폴더(디렉터리)가 패키지로 인식되도록 하는 역할도 하고, 이름 그대로 패키지를 초기화하는 역할을 한다. 즉, import로 패키지를 가져오면 init.py 파일이 실행되므로 이 파일에서 from . import 모듈 형식으로 현재 패키지에서 모듈을 가져오게 만들어야 한다.
※ 참고로 python3.3 버전부터는 init.py 파일이 없어도 패키지로 인식한다(PEP 420). 하지만 하위 버전 호환을 위해 init.py 파일을 생성하는 것이 안전한 방법이다.
(출처 : https://velog.io/@limes/Python-init.py-%ED%8C%8C%EC%9D%BC%EC%9D%98-%EC%97%AD%ED%95%A0)