TIL16 | Python Modules & Packages, 절대경로와 상대경로

2021. 10. 11. 13:32언어/Python

반응형

sys.modulessys.path의 차이점

파이썬이 module과 package를 검색하는 순서

  1. sys.modules
  2. built-in modules
  3. sys.path

만약 3개 구역에서 찾지 못한다면 ModuleNotFoundError 발생

sys.modules

  • 단순한 dictionary
  • 이미 import된 모듈과 package들을 저장하고 있다. 새로 import하는 모듈은 없음
  • 한번 import된 모듈과 package들은 파이썬이 또 다시 찾지 않아도 되도록 하는 기능

built-in modules

  • 파이썬에서 제공하는 파이썬 공식 라이브러리
  • 이미 파이썬에 포함되어 나오므로 파이썬이 쉽게 찾을 수 있다.

sys.path

  • string 요소들을 가지고 있는 list
  • 각 string 요소들은 경로를 나타낸다.
  • 파이썬은 list의 각 경로들을 확인하면서 해당 경로에 import하고자 하는 package가 위치해 있는지 확인한다.

 

파이썬은 sys 모듈의 위치를 어떻게 찾을 수 있을까?

sys

sys모듈은 설치했을 때 설정되는 built-in 으로 되어있다.

 

Absolute path & Relative path

파이썬의 built-in 모듈과 pip을 통해 설치한 외부 모듈 및 패키지는 일반적으로 import하는데 큰 문제가 되지 않는다.
pip으로 설치한 외부 모듈은 자동으로 site-packages라는 디렉토리에 설치가 되는데 이 디렉토리는 sys.path에 이미 포함되어 있다.

직접 개발한 local package를 import하는 경로에는 absolute path와 relative path가 있다.

absolute path(절대 경로)

  • 최상단 디렉토리를 기준으로 경로를 표현

  • import를 하는 파일이나 경로에 상관없이 항상 경로가 동일

  • 경로가 길어질 수 있다는 단점이 있으나 relative path의 단점을 고려하면 absolute path를 권장

relative path(상대 경로)

  • import하는 위치를 기준으로 경로를 정의
  • 일반적으로 local package안에서 다른 local package를 import할 때 사용
  • 선언해야 하는 경로의 길이를 줄여준다는 장점이 있지만 헷갈리기 쉽고, 파일의 위치가 변경되면 경로위치도 변경되어야 함

 

calculator 패키지 만들기

디렉토리 구조와 각 파일의 코드내용은 다음과 같다.

__init__.py 파일에는 아무코드도 없지만 init 파일은 해당 디렉토리가 패키지임을 알려주는 역할을 한다.

img

main.py

# 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))

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

def multiply(a,b):
    return(a*b)

 

main.py에서 상대경로로 add_and_mutiply 를 임포트 했을 때 발생하는 에러

Traceback (most recent call last):
  File "main.py", line 6, in <module>
    from .calculator.add_and_multiply import add_and_multiply
ModuleNotFoundError: No module named '__main__.calculator'; '__main__' is not a package

 

에러 발생 원인

파이썬 공식 문서를 확인하면 다음과 같이 기재되어 있다.

파이썬 응용 프로그램의 main module("_main_")로 사용될 목적의 모듈들은 반드시 절대 경로를 사용해야 한다.

image

main.py의 import 상대경로를 절대경로로 수정하면 정상 실행된다.

# absoulte path
from calculator.add_and_multiply import add_and_multiply 

if __name__ == '__main__':
 print(add_and_multiply(1,2))

 

add_and_multiply.py에서 multiply함수를 절대경로와 상대경로 각각 임포트 해보고 main 모듈과 차이점을 생각해보기

main

add_and_multiply.py 에서 multiply 함수를 절대경로나 상대경로로 임포트 했을 때 결과는 동일하게 잘 실행 되었다. main.pyadd_and_multiply.py파일에서 _name_을 출력했을 때 위와 같이 기본 모듈이 main.py 로 실행되었음을 확인할 수 있었다.

정리하자면, 기본 모듈은 다른 패키지나 모듈을 임포트할 때 절대경로로 불러와야 하며, 기본 모듈이 아닌 경우는 절대경로든 상대경로든 상관없이 사용할 수 있다.

 

__init__.py 파일의 역할

  • init 파일은 해당 디렉토리가 패키지임을 알려주는 역할을 한다.
  • Python3.3 이전 버전에서는 디렉토리에 _init_.py 파일이 없다면 패키지로 인식되지 않을 수도 있다.
반응형