TIL 017 | How import statement finds modules and packages

This Is Empty.·2021년 9월 4일
0

TIL

목록 보기
17/23
post-thumbnail

How import statement finds modules and packages

파이썬은 module / package를 찾을 때 다음 3가지 장소를 순서대로 보면서 찾는다.

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

sys.modules

sys.modulespythonmodule이나 package를 찾기 위해 우선적으로 살피는 영역으로 dictionary형태로 되어있다. 그리고 이미 importmodulepackage들을 저장하고 있기때문에 한번 importmodulepacakge들을 python이 또 다시 찾지 않아도 된다. 때문에 새로 import하는 모듈은 sys.modules에서 찾을 수 없다.

built-in modeles

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

사진에서 importdatetimebuilt-in module이다.

import하지 않으면 사용할 수 없다.

이 외에도 여기에서 python이 제공하는 다양한 built-in module들을 확인 할 수 있다.

sys.path

sys.pathsys.modules과 다르게 string요소들을 가지고 있는 list이다.
파이썬은 list의 각 경로를 하나하나 확인하면서 해당 경로에 import하고자 하는 package가 있는지 확인한다.

파이썬은 sys.modules -> built-in module -> sys.path 순서로 확인하므로, sys.path에서도 찾지 못하면 ModuleNotFoundError를 리턴한다.

sys.path에 정의되어 있는 디렉터리는 크게 3가지로 나눌 수 있다.

  • python 모듈이 실행되고 있는 현재 디렉터리
  • PYTHONPATH 환경변수에 정의되어 있는 디렉터리
  • python과 함께 설치된 기본 라이브러리

Absolute path & Relative Path

pythonbuilt-in modulepip를 통해 설치한 외부 modulepackage는 파이썬이 쉽게 찾을 수 있다. pip로 설치한 외부 모듈은 site-packages라는 디렉토리에 설치되어 sys.path에 포함되기 때문이다.

하지만 직접 개발한 local pacageimport할때는 위치에 맞게 import경로를 잘 선언해야 한다.

Absolute path : 절대경로

Absolute path(절대경로)는 기존 디렉토리에 관계없이 파일이나 폴더의 위치를 ..(파이썬에서는 경로구분을 /이 아닌 .으로 한다)으로 설명하는 경로이다. 프로그래밍 상에서 절대경로를 알고있으면 현재 파일의 위치에 상관없이 그 경로로 접근이 가능하다. 절대경로는 최상위 디렉터리를 기준으로 한다.


위 파일 구조에서 main.py의 절대경로는 /Users/dabeen/workSpace/cal_package/main.py 이다.

relative path : 상대경로

relative path(상대경로)는 현재 작업 디렉토리를 기준으로 파일 또는 폴더의 위치를 설명하는 경로다. 절대경로와 달리 상대경로에는 단일 웹사이트 내의 기존 문서에 대한 완전한 정보만 포함되므로 완전한 절대 경로를 제공할 필요가 없다. 즉, 최 상단 디렉토리를 기준으로 경로를 잡는게 아니라 import하는 위치를 기준으로 경로를 정의한다.

sys 모듈의 위치

import sys
sys.builtin_module_name

으로 built-in된 모듈들을 확인할 수 있다.(내장 모듈 목록을 tuple로 반환한다)

따라서 sys인터프리터에 내장되어있다.

calculator 패키지

  • main.py
  • multiplication.py
  • add_and_multiply.py
  • __init__.py
    해당 파일에는 아무 코드도 없지만 해당 디렉터리가 메인 패키지 임을 알려주는 역할을 한다.

init.py의 역할

05-3 패키지
init.py 파일은 해당 디렉터리가 패키지의 일부임을 알려주는 역할을 한다. 만약 game, sound, graphic 등 패키지에 포함된 디렉터리에 init.py 파일이 없다면 패키지로 인식되지 않는다.

※ python3.3 버전부터는 init.py 파일이 없어도 패키지로 인식한다(PEP 420). 하지만 하위 버전 호환을 위해 init.py 파일을 생성하는 것이 안전한 방법이다.

main.py 에서 상대경로로 add_and_multiply를 import할 수 있을까?

main.py에서 상대경로로 add_and_multyplyimport할 경우 TypeError: 'module' object is not callable에러가 발생한다.

6. modules
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.

간단히 말하자면, 파이썬 애플리케이션의 메인 모듈로 사용되는 모듈은 항상 절대 가져오기를 사용해야 한다.


절대경로로 수정 한 후에는 정상 동작하는것을 확인할 수 있다.

add_and_multiply.py 에서 multiply함수 import

  • 상대경로로 import

  • 결과

ImportError: attempted relative import with no known parent package가 발생한다.

위의 경우와 동일하게 add_and_multiply.py__main__이 되므로 상대경로는 사용이 불가능하고 절대경로를 사용해야 한다.

  • 절대경로로 import
  • 결과

예상과는 달리ModuleNotFoundError: No module named 'calculator' 오류가 발생했다.

이유는 절대경로로 import할때에는 현재의 디렉토리가 sys.path에 포함되기 때문이다.
multiplyadd_and_multiply와 같은 디렉토리 내에 있으므로 아래와 같이 사용하면 정상 동작한다.

profile
Convinced myself, I seek not to convince.

0개의 댓글