sys.modules은 파이썬이 모듈이나 패키지를 찾기 위해 가장 먼저 찾는 곳이며, 딕셔너리로 구성되어 관리되고 있다.
sys.path은 파이썬이 모듈이나 패키지를 찾는 가장 마지막 장소이며, import된 모듈의 경로를 string의 값으로 list(배열)에 저장되어 관리 된다.
sys module은 파이썬 built_in modules에 포함되어 있는 module 이기에 sys.modules나 sys.path에서 위치를 찾을 수 있다.
import를 하는 파일이나 경로에 상관없이 항상 경로가 동일하다.
일반적으로 직접 개발한 local package를 import 할 때는 absolute path를 사용경로가 길어질 수 있다.
current directory(현재 디렉토리)는 default로 sys.path에 포함 되어 있기에 absolute path는 현재 디렉토리(최상단)로 부터 경로를 시작하게 된다.
from package.subpackage.module import function
#파이썬은 dot(.)을 사용해 경로 표현
-경로를 import 하는 위치를 기준으로 정의한다(absolute 처럼 최상단 디렉토리 기준으로 경로를 잡는게 아님)
-dot(.); import가 선언되는 파일의 현재 위치
-two dots(..); 현재 위치에서 상위 디렉토리로 가는 경로
-경로가 길어질 수 있는 absolute path의 단점을 보완하기 위해 사용 가능
-헷갈리기 쉽고, 파일 위치가 변경되면 경로 위치도 변경되어야 하는 단점
-가급적 absolue path 사용하는 걸 권장
-일반적으로 local package 안에서 다른 local package를 import 할 때 사용
#해당 디렉토리에서 찾기
from .import class1
from .subpackage1.module1 import function1
#여기서 dot(.)은 import가 선언되는 파일의 현재 위치
#현재 위치에서부터 원하는 모듈의 경로만 선언 해주면 됨
#상위 디렉토리로 올라가서 찾기
from ..module4 import class4
#dot(.) 2개를 사용할 수 있음
#2개는 현재위치에서 상위 디렉토리로 가는 경로
main.py
# Absolute Path (실행 진행)
from calculator.add_and_multiply import add_and_multiply
#Relative Path (실행 오류)
#ImportError: attempted relative import with no known parent package)
#.from calculator.add_and_multiply import add_and_multiply
if __name__ == '__main__':
print(add_and_multiply(1,2))
main.py 실행
add_and_multiply를 main모듈에 import할 때 절대경로 사용
add_and_multiply에서 multiplication를 import할때 절대경로,상대경로 모두 사용 가능
add_and_multiply 실행
multiplication를 import할때 calculator 포함시 오류 발생
아래와 같이 모듈만 인식 가능
add_and_multiply.py
from multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
print(add_and_multiply(1,2))
(https://docs.python.org/3/tutorial/modules.html#intra-package-references)
위에서 작성한 코드를 실행시켜보면 다음과 같은 에러가 발생한다.
부모 패키지가 정의되어있지 않은 상태에서 상대 경로로 import를 시도해서 발생한 import error다.
-절대경로로 import 경로를 정의해줄 것.
-파이썬 공식문서를 참고해보면 다음과 같이 권고하는데,
Note that relative imports are based on the name of the current module. 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.
즉, 상대 경로 import는 현재 모듈의 이름을 기반으로한다. 기본 모듈의 이름은 항상 main이므로 Python 응용 프로그램의 기본 모듈로 사용하려는 모듈은 항상 절대 가져 오기를 사용해야한다. 이제 위의 내용들을 참고하여 절대 경로로 변경하여 오류를 해결 후 결과를 출력해보자.
✨ 오류 해결
출력 결과
• 절대 경로
from calculator.multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
• 상대 경로
from .multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
• 실행 결과
실행 결과는 동일하다.
add_and_multiply.py는 main.py가 아니기 때문에 절대 경로든 상대 경로든 문제 없이 동작한다. main.py가 아니면 절대 경로든 상대 경로든 작동에는 문제가 없다.
-init.py 파일이 존재하지 않는다면 패키지의 일부인지 인식을 하지 못하기 때문에 속성을 가지고 있지 않는다는 에러가 발생하게 된다.
-현재는 init.py파일은 빈 파일이지만 package 실행 시 설정해주고 싶은 초기 설정이 있다면 이 파일에 초기 설정에 관련된 코드들을 작성해준다. 그러면 작성 한 코드의 내용대로 package 실행 시 자동으로 실행된다.