How Import Statement Finds Modules & Packages

j·2022년 5월 5일
0

TIL

목록 보기
2/14
post-thumbnail

Import Search 순서

module일 경우에는 파이썬 파일, package의 경우 파이썬 파일들은 담고 있는 디렉토리들을 파이썬이 찾아야 import를 한다.
파이썬은 3가지 장소를 순서대로 보면서 찾는다.

sys.modules → built-in mudules → sys.path

  • sys.modules

    파이썬이 module이나 package를 찾기위해 가장 먼저 확인하는 곳으로 단순한 dictionary이다. 그리고 이미 import된 module과 package들을 저장하고 있어서 한번 import된 module과 package들은 파이썬이 다시 찾지 않아도 되도록한다. 이말은 즉 새로 import하는 moduledms sys.modules에서 찾을수 없다.

  • built-in modules

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

  • sys.path

    마지막으로 확인하는 장소가 sys.path이다. 기본적으로 list이며 string 요소들을 가지고 있는 list이다. 파이썬은 list의 각 경로를 하나하나 확인하면서 해당 경로에 import하고자 하는 package가 위치해 있는지 확인한다.

sys.path에서도 못찾으면 ModuleNotFoundError 에러를 리턴한다

Absolute Path & Relative Path

파이썬의 built-in 모듈과 pip를 통해 설치한 외부 모듈 및 package는 일반적으로 import 하는데 큰 문제가 되지 않는다.
문제는 직접 개발한 local package이다. 직접 개발한 local package를 import할때는 해당 Package의 위치에 맞게 import경로를 잘 선언해야한다.

Absolute Path

  • 절대 경로
  • import를 하는 파일이나 경로에 상관없이 프로젝트의 최상단 디렉토리를 기준으로 경로를 잡는다.
  • 일반적으로 local package를 import를 할때는 absolute path를 사용
  • 그러나 경로가 길어질 수 있다는 단점이 있다.

Relative Path

  • 절대 경로의 단점(긴 경로)을 보완하기 위해 사용
  • import하는 위치를 기준으로 경로를 정의한다.
  • 일반적으로 local package 안에서 다른 local package를 import할 때 사용
  • 여기서 dot(.)은 import가 선언되는 파일의 현재 위치
  • dot 2개(..)는 현재위치에서 상위 디렉토리로 가는 경로
  • 경로 길이를 줄여준다는 장점이 있지만 헷갈리기 쉽고 파일의 위치가 바뀌는 경우 경로또한 수정해주어야 하는 단점이 있어서 웬만하면 absolute path 사용하는것이 좋다.

Example

└── my_app
    ├── main.py
    ├── package1
    │   ├── module1.py
    │   └── module2.py
    └── package2
        ├── __init__.py
        ├── module3.py
        ├── module4.py
        └── subpackage1
            └── module5.py

위의 프로젝트를 예로 들어보자.

  • Absolute path를 사용해 package1package2 를 import 하는 경우
    경로들이 전부 my_app 안의 최상위 디렉토리에서 시작한다. (이미 my_app 프로젝트 안에 있으므로 my_app 은 생략한다.)
  • Relative Path를 사용해 package2-module3에서 package2-class1package2-subpackage1-module5-function2를 import하는 경우

sys.modulessys.path 의 차이점

sys.modules은 단순한 dictionary이고 sys.path는 string요소들을 가지고 있는 list이다.

✅ sys도 import 해야하는 모듈인데 파이썬은 sys 모듈의 위치를 어떻게 찾을 수 있는지

sys모듈을 파이썬에 포함된 모듈이기때문에 built-in modules에서 찾을 수 있다.

absolute pathrelative path 의 차이점

absolute path는 import를 하는 파일이나 경로에 상관없이 프로젝트의 최상단 디렉토리를 기준으로 경로를 잡고, relative path는 import하는 위치를 기준으로 경로를 정의한다.


Practice : calculator 패키지 만들기

다음과 같은 구조를가진 디렉토리와 파일들이 있다.

main.py에서 상대경로로 add_and_multiply를 import하게되면 다음과 같은 에러가 발생한다. 공식문서를 찾아보면 해답이 나와있다. 상대경로는 현재 모듈의 이름을 기반으로 import한다. 하지만 main module의 이름은 항상 __main__ 이기 때문에 파이썬 어플리케이션의 main module로 쓰게되는 모듈은 항상 절대경로를 사용해야한다.

main모듈과는 다르게 add_and_multiply.py에서 multiply함수를 import할때는 절대경로와 상대경로 둘 다 사용가능하며 정상적으로 출력된다.

__init__.py 파일의 역할

__init__.py 파일은 해당 디렉터리가 패키지의 일부임을 알려주는 역할을 한다.
⚠️ python3.3 버전부터는 __init__.py 파일이 없어도 패키지로 인식한다(PEP 420). 하지만 하위 버전 호환을 위해 __init__.py 파일을 생성하는 것이 안전하다.

Reference
https://docs.python.org/3/tutorial/modules.html#intra-package-references
https://www.python.org/dev/peps/pep-0420/
https://wikidocs.net/1418#9595init9595py

profile
개발 공부 기록

0개의 댓글