TIL | python modules & packages
module & package
파이썬의 module은 variable, def, class 들을 모아둔 하나의 .py
파일이다. package는 그 모듈 파일들의 컨테이너로 여러 모듈들이 담겨져 있는 디렉토리로 볼 수 있다. 하나의 패키지에는 단지 모듈들만 포함 되어 있는 것이 아닌 서브 패키지가 하위로 존재할 수 있다.
파이썬에서 모듈과 패키지를 찾는 과정
파이썬에서 모듈을 사용하기 위해 import
라는 키워드를 통해 모듈을 불러 올 수 있는데 파이썬은 sys.modules
, built-in.modules
, sys.path
를 순서대로 검색하여 해당 모듈을 찾는다. 만약 찾지 못하면 ModuleNotFoundError
에러를 리턴한다.
sys.modules
파이썬의 모듈이나 패키지를 찾기 위해 제일 먼저 확인하는 곳이다. sys.modules는 이미 import된 모듈과 패키지들을 저장해 놓은 딕셔너리이다. 한 번 import된 모듈과 패키지들은 파이썬이 또 다시 찾지 않도록 하는 기능을 가졌다.
built-in modules
파이썬에서 제공하는 파이썬 공식 라이브러리들이다. built-in 모듈들은 이미 파이썬에 포함되어 나온다. 그러므로 파이썬이 쉽게 찾고 읽을 수 있다.
sys.path
list 자료 타입이며 모듈과 패키지들의 경로 정보를 담은 string 타입의 요소들이 담겨 있다. 파이썬은 sys.path의 요소들을 하나 하나 검색해 가며 해당 경로에 import 하고자 하는 패키지가 위치해 있는 지 확인한다.
sys 모듈
sys
는 파이썬 기본 내장 라이브러리에 포함 되어 있는 모듈이다. 따라서 sys 모듈을 임포트한 후, sys.modules와 sys.path를 출력하면 값을 확인할 수 있다.
# sys module 임포트
import sys
# sys.modules 출력
print(sys.modules)
{...} # dictionary
# sys.path 출력
print(sys.path)
[...] # list
sys.modules
와 sys.path
는 각각 딕셔너리, 리스트 타입으로 각각 다른 자료 구조로 되어 있으며 sys.modules은 import된 모듈과 패키지를 다시 찾지 않아도 되는 기능이 있다. 그러나 sys.path는 list 속 요소인 검색 경로들을 하나 씩 확인하는 방식으로 파이썬이 모듈을 찾아야 하는 차이가 있다.
Absolute path (절대 경로) & Relative path (상대 경로)
일반적으로 import를 하여 해당 모듈이나 패키지를 쉽게 찾을 수 있지만 직접 개발한 local package를 import할 때는 해당 패키지의 위치에 맞게 경로를 선언해야 정확히 임포트 할 수 있다.
Absoulute path (절대 경로)
Absolute path는 이름 그대로 절대 경로이다. 왜 절대 경로인가. import를 하는 파일이나 경로에 상관없이 항상 경로가 동일하기 때문이다. 다음의 my_app이란 프로젝트 내에서 package1과 package2를 임포트 하는 경우에는 최상위 디렉토리인 my_app에서 경로를 표시한다.
- my_app
- main.py
- package1
- modul1.py
- modul2.py
- package2
- init.py
- module3.py
- subpackage1
- module5.py
from package1 import module1
from package1.module2 import function2
from package2 import class1
from package2.subpackage1.module5 import function2
Relative path (상대 경로)
# 현재 위치
# package1/module2.py
from . import class1
from .subpackage1.module5 import function2
Relative path란 import를 하는 위치를 기준으로 경로를 정의하는 방식이다. .
은 현재 위치를 뜻하는 것으로 절대 경로와 같이 현재 위치의 최상단부터 작성하지 않아도 .
으로 현재 위치를 표기할 수 있다. ..
도 사용할 수 있는데 이는 현재 위치의 상위 디렉토리로 가는 경로를 뜻한다. 절대 경로와 달리 경로 값이 짧아져서 유용하지만 방대한 양의 데이터에서는 헷갈리기 쉽고 파일 위치가 변경되면 경로 위치도 변경되어야 하는 단점이 있다. 그러므로 보통 절대 경로를 사용하는 것을 권장한다.
__init__.py
__init__.py
파일 패키지에 있는 파일로 아무 내용을 담지 않아도 패키지 디렉토리에 존재함으로서 이 폴더가 패키지임을 인식(파이썬 3.3 이상부터는 __init__.py
이 없어도 패키지로 인식)시킨다. __init__.py
는 패키지의 초기 설정을 할 수 있는 파일이며, 패키지가 import 될 때, 자동으로 실행된다. 패키지 내부에서 특정 함수나 모듈, 변수 등을 제한하여 import 하도록 설정하고 싶은 경우 __all__
변수에 정의함으로써 가능하다.
만약 calculator_package
라는 패키지를 만든다고 하자. 먼저 디렉토리를 생성하고 __init__.py
파일을 저장한다. 그 다음 원하는 모듈이름.py
모듈 파일을 패키지 디렉토리에 저장한다.
calculator_package 구조
calculator_package
에는 __init__.py
파일, multiplication.py
, add_and_multiply.py
두 개의 모듈이 포함 되어 있으며 calculator_package 그 상단 디렉토리에는 main.py 라는 실행 파이썬 파일이 존재한다.
- calculator_package
__init__.py
multiplication.py
add_and_multiply.py- main.py
multiplication 모듈
def multiply(a,b):
return(a*b)
add_and_multiply 모듈
# 절대 경로로 multiply 모듈 import
from calculator_package.multiplication import multiply
# 상대 경로로 multiply 모듈 import
# from .multiplication import multiply
def add_and_multiply(a,b):
return multiply(a,b) + (a+b)
main.py 에서의 실행
main.py에서 calculator_package
의 add_and_multiply
를 임포트 한다고 가정하자. calculator_package와 같은 디렉토리에 속해 있는 main.py
는 임포트 방식에서 절대 경로와 상대 경로를 사용한 경우, 상대 경로를 사용한 쪽에서 에러가 난다.
# main.py
# 절대 경로로 임포트 하는 경우
from calculator_package.add_and_multiply import add_and_multiply
print(add_and_multiply(1,2))
# 5
# 상대 경로로 임포트 하는 경우
from .calculator_package.add_and_multiply import add_and_multiply
print(add_and_multiply(1,2))
# ImportError: attempted relative import with no known parent package
그 이유는 .
을 사용한 동시에 경로는 현재의 위치(main.py)를 의미하게 된다. 결국 main.py 파일에서의 calculator_package를 찾게 되고 이는 main.py에서 존재하지 않는 모듈 혹은 파일이므로 임포트 오류가 난다. 어떤 경로 위치에서 어떻게 import를 하느냐는 매우 중요하다. 상대 경로는 절대 경로에 비해 간단하지만 현재의 위치 파악이 중요해 상대적으로 복잡한 특징을 지니고 있다.
Author And Source
이 문제에 관하여(TIL | python modules & packages), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@tiiranocode/TIL-python-modules-packages저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)