[TIL / Python] 파이썬 문법4 (Modules, Packages)

나른한 개발자·2022년 1월 3일
0

studylog

목록 보기
17/45
  1. 모듈 / 패키지 import하기
  2. Absolute Path / Relative Path
  3. sys.module과 sys.path의 차이점

1. 모듈/패키지 import하기

파이썬에서는 import.모듈 또는 from 모듈 import 이름로 모듈을 가져올 수 있다.

import my_import

위와 같은 코드를 추가 했을 때 파이썬은 sys.modules - built-in modules - sys.path 순으로 모듈/패키지를 찾는다.

sys.modules
sys는 파이썬에 포함되어있는 모듈이며, sys.modules은 이미 import된 모듈 및 패키지를 저장하는 디렉터리이다. 따라서 새로이 import되는 것들은 이곳에서 찾을 수 없다.

built-in modules
파이썬에서 제공하는 공식 라이브러리이며, 찾는 모듈/패키지가 sys.modules에 없을 때 그 다음으로 찾아보는 곳이다.

sys.path
sys.path는 아래와 같이 string타입의 경로를 요소로 가지는 list이다.

['',
 '/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']

리스트에 저장되어 있는 리스트를 확인하면서 찾고자하는 모듈/패키지가 있는지 검색한다.

pip으로 외부 모듈을 설치 시 자동으로 site-pakages에 설치되는데 site-pakages 역시 sys.path에 포함되어 있어 pip으로 설치한 모듈/패키지도 여기서 찾을 수 있다.

여기까지 검색을 했는데도 찾을 수 없는 경우 ModuleNotFoundError 를 일으킨다.

sys.module과 sys.path의 차이점

  • sys.module: 파이썬이 모듈/패키지를 찾기 위해 가장 먼저 탐색하는 곳으로 딕셔너리 형태이다.
  • sys.path: string을 값으로 가지는 List이다.

2. Absolute Path / Relative Path

직접 작성한 local pakage의 경우 경로가 파이썬이 모듈/패키지를 잘 찾을 수 있도록 경로를 잘 명시해주는 것이 중요하다.

Absolute Path

경로가 최상단 디렉터리부터 시작하며 같은 프로젝트 내의 어떤 파일, 경로나 상관없이 항상 동일한 경로이다.

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

위와 같은 구조를 가진 프로젝트가 있다고 하자. module5.py와 module1.py내의 func1을 import한다고 하면 다음과 같이 경로를 지정한다.

from pakage2.subpakage2 import module5.py
from pakage1.module2.py import func1

Relative Path

absolute path의 단점은 경로가 길어질 수 있다는 점이다.
반면 Relative Path는 현재 import를 하는 위치를 기준으로 경로를 정의한다. 따라서 Relative Path는 Local Pakage 내에서 다른 Local Pakage를 import할 때 사용한다.

예를 들어, pakage2의 module4.py에서 module1.py와 module5.py, moulde4.py에 있는 class1을 import한다면 다음과 같이 경로가 지정될 것이다.

from . import class1
from .subpakage1 import module5.py
from ..module4 import class4

.(dot)은 현재 위치를 나타내고 상위 디렉터리로 가고 싶으면 ..을 쓴다. 상대 경로는 경로를 단축화할 수 있으나 파일의 경로가 달라질 경우 import 경로도 모두 수정을 해줘야하기 때문에 절대 경로를 더 권장한다.

4. main.py의 import

main.py 에서 상대 경로로 다른 메서드를 import한다면 다음과 같은 에러를 볼 수 있다.

ImportError: attempted relative import with no known parent package

앞서 상대 경로는 자신의 위치를 잡기 위해 __name자신의 현재 모듈 이름을 기반으로 위치를 잡는 것인데, main 모듈은 항상 '__main' 이기 때문에 main 모듈에서는 절대 경로로 지정해줘야 한다.

활용

    ├── main.py
    ├── calculator
        ├── __init__.py
        ├── add_and_multiply.py
        └── multiplication.py

위와 같은 구조를 가진 패키지가 있다고 할 때, add_and_multiply.py에서 multiplication.py 내의 multiply 함수를 import 한다고 하자.

다음과 같이 작성할 수 있을 것이다.

from calculator.multiplication.py import multiply # 절대 경로
from .multiplication.py import multiply # 상대 경로

이때 상대 경로로 작성하면 오류가 나는데, main.py에서 처럼 main module인 add_and_multiply.py를 찾지 못해서 나오는 오류이다.

5. __init__.py

  • __init.py__는 해당 디렉터리가 패키지임을 보여준다. (python3.3 부터는 없어도 패키지로 인식하지만 하위 버전을 고려하여 생성하는 것이 나음)

  • import하면 이 파일이 실행되며 초기화를 하기도 한다. 예를 들어 패키지 내의 모든 모듈들이 공통으로 사용하는 외부 모듈 / 패키지가 있다면 이 파일에 import하여 패키지 전체에서 쓸 수 있도록 한다.

참고:
Calculator 패키지 만들기
[파이썬 상대경로 import 에러] ImportError: attempted relative import with no known parent package

profile
Start fast to fail fast

0개의 댓글