[Python] How Import Statement Finds Modules & Packages

ㅎㅎ·2021년 6월 11일
0

Python

목록 보기
24/27

📌 How Import Statement Finds Modules & Packages

파이썬이 module과 package를 검색하는 방법을 알아봅세.
파이썬은 sys.module ➡️ built-in modules ➡️ sys.path순으로 파일이나 디렉토리를 찾는다.

- sys.modules.

  • 파이썬이 모듈이나 패키지를 찾기위해 가장 먼저 확인하는 곳
  • sys.modules 는 단순한 딕셔너리이다. 그리고 이미 import된 모듈이 패키지를 저장하고 있다.즉 한번 import된 모듈과 패키지들은 파이썬이 또 찾이 않아도 된다. 그리고 새로 import하는 모듈은 sys.modules에서 찾을 수 없더

- built-in modules

  • 파이썬에서 제공하는 파이썬 공식 라이브러리
  • 이 모듈들은 이미 파이썬에서 포함되어 있어서 파이썬이 쉽게 찾을 수 있다.

- sys.path

  • 파이썬이 마지막으로 확인하는 곳
  • sys.path는 기본적으로 list이며 str 요소들을 가지고 있다. 밑의 코드처럼 str 요소들은 경로를 나타낸다. 즉 파이썬은 리스트의 경로를 하나하나 확인하면서 해당 경로에 import하고자 하는 패지키가 있는지확인한다.
['',
 '/Users/song-eun-u/anaconda3/bin',
 '/Users/song-eun-u/anaconda3/lib/python36.zip',
 '/Users/song-eun-u/anaconda3/lib/python3.6',
 '/Users/song-eun-u/anaconda3/lib/python3.6/lib-dynload',
 '/Users/song-eun-u/anaconda3/lib/python3.6/site-packages',
 '/Users/song-eun-u/anaconda3/lib/python3.6/site-packages/aeosa',
 '/Users/song-eun-u/anaconda3/lib/python3.6/site-packages/IPython/extensions',
 '/Users/song-eun-u/.ipython']

+) 참고로 sys는 파이썬 모듈이다 따라서 다음과 같이 sys 모듈을 import해서 출력, 수정도 가능하다.

import sys

print(sys.path)
print(sys.modules) 


📌 Absolute Path & Relative Path

  • 보통 파이썬의 built-in modulespip를 통해 설치한 외부 모듈, 패키지는 일반적으로 import할때 문제가 생기지 않는다.
  • 하지만 문제는 직접 개발한 local package이다. 이 패키지를 사용할때는해당 위치의 패키지에 맞게 import 경로를 잘 선언해야한다.
  • 이 local package를 import하는 경로는 Absolute Path(절대 경로 ) & Relative Path(상대경로)가 있다.
└── my_app
    ├── main.py
    ├── package1
    │   ├── module1.py
    │   └── module2.py
    └── package2
        ├── __init__.py
        ├── module3.py
        ├── module4.py
        └── subpackage1
            └── module5.py
  • 위의 프로젝트를 예를 들면, my_app이라는 프로젝트에 package1, package가 있고, package2에는 subpackage2라는 중첩 패키지를 가지고 있다 .

- Absolute Path

만약 absolute path (절대 경로)를 사용해서 package1, package2를 Import하면 다음과 같다.

from package1 import module1
from package1.module2 import function1
from package2 import class1
from package2.subpackage1.module5 import function2

보면 경로들의 시작점이 전부 my_app 프로젝트의 가장 최상위 디렉토리에서 시작하는 것을 알 수 있다. 예를들어 subpackage1module5 모듈의 function 함수를 import를 하려면 다음과 같은 경로를 거친다.

 my_app => package2 => subpackage1 => module5.py

이를 리눅스 디렉토리 경로 형식으로 바꾸면 !

my_app/package2/subpackage1/module5.py

# 파이썬에서는 /대신 .를 붙여 경로를 표현 
my_app.package2.subpackage1.module5.py

# my_app 프로젝트 안에 있으므로 생략 따라서 다음과 같이 경로 표현
package2.subpackage1.module5.py

# 이를 from import 키워드를 사용해 표현하면,
from package2.subpackage1.module5 import function2

➡️ 위와 같이 my_app 프로젝트 내에서는 어느 파일, 어프 위치에서 import 하던지 경로가 항상 위와 같이 동일하게 되므로 absolute path(절대 경로) 라고 한다. 일반적으로 local package를 import할 때는 절대 경로를 사용한다.

하지만 절대 경로는 경로가 길어질수 있다는 단점이 존재한다.
따라서 이러한 단점을 보완하기 위해서 realtive path(상대 경로)를 사용할 수 있다 .

- Relative Path

  • Relative Path(상대 경로)는 절대 경로와 같이 프로젝트의 최상단 디렉토리를 기준으로 하는 것이 아니라 import하는 위치를 기준으로 경로를 정의한다. 따라서 주로 상대 경로는 local package 안에서 다른 local package를 import할 때 사용한다.

  • 위의 예시를 다시 가져오면, 예를 들어, package2module3에서 package2class1package2의 하위 package인 subpackage1module5function2 함수를 import 할때는 다음과 같이 만들면 된다.

# package2/module3.py  -> 파일 이름 & 현재 위치

from . import class1
from .subpackage1.module5 import function2
  • . 는 파일의 현재 위치를 의미하고, .. 는 현재위치에서 상위 디렉토리로 가는 경로이다.
  • 하지만 상대경로는 길이를 줄여준다는 장점이 있지만 헷갈리기 쉽고 파일 위치가 변경되었을 때 경로 위치도 바꿔줘야 한다는 단점이 있으므로 절대 경로를 사용하는 것이 좋다 .

📌 문제

- sys.modules와 sys.path의 차이점

  • sys.modules는 파이썬 모듈이나 패키지를 찾을 대 가장 먼저 확인하는 곳이고, sys.path는 가장 마지막으로 확인하는 곳이다.

- sys도 import 해야하는 모듈입니다. 파이썬은 sys모듈의 위치를 어떻게 찾을까요?

  • sys.module ➡️ built-in modules ➡️ sys.path 순으로 찾는데. sys 모듈은 파이썬 built_in_modules에 포함되어 있는 모듈이기에 sys모듈을 출력해 sys.modulessys.path를 출력한다.

0개의 댓글