[Modules & Packages]

jaylight·2020년 11월 21일
0

sys.modules와 sys.path의 차이점

import를 통해 모듈을 import할 경우,

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

순서로 탐색한다.

순서상, 파이썬에 이미 import된 모듈의 딕셔너리인 sys.modules → 파이썬 내부에 위치하지만 아직 import되지 않은 built-in modules → 탐색 순서sys.path()에 따른 외부 경로 차례로 모듈을 탐색한다.

sys.modules

  • 파이썬 실행 프로그램이 모듈이나 패키지를 찾기 위해 가장 먼저 확인하는 딕셔너리로, 이미 import된 모듈과 패키지들을 저장하고 있음

built-in Modules

  • built-in Modules는 파이썬 외부 경로에 모듈이 위치해있지 않고, 내부에 built-in 되어 있어 외부 탐색 없이 import할 수 있는 모듈이다.

빌트인 함수와 빌트인 모듈은 다르다.
빌트인 함수들은 import 없이 바로 접근하여 사용 가능하지만, 빌트인 모듈은 import한 뒤 접근하여 사용 가능함

sys.path

  • sys.modules()와 built-in modules를 통해 원하는 모듈을 찾지 못했을 경우,
    사전에 정의된 경로 순서에 따라 모듈을 찾는다.
  • 해당 경로 순서는 sys.path()리스트의 형태로 정의되어 있으며,
  • 실행 프로그램의 필요에 따라 해당 리스트를 불러와 탐색 경로를 수정할 수 있다.
  • sys.path의 요소 중 ''로 빈 문자열로 저장된 항목은 해당 실행 프로그램이 위치한 디렉토리를 탐색하는 작업을 수행한다.
  • 만약 경로를 탐색하며 원하는 모듈을 찾는 중 동일한 이름의 모듈이 중복되어 발견된다면, 먼저 등장한 모듈을 활용한다.
    (즉, sys.path()상에서 표준 라이브러리를 찾는 경로 이전의 경로에서 표준 라이브러리와 같은 이름의 모듈을 발견한다면, 해당 모듈을 사용)

만약 위 순서로 탐색했음에도 원하는 모듈을 찾지 못한다면, ModuleNotFoundError를 반환한다.

sys 모듈의 위치를 찾는 법

sys는 파이썬 built-in 모듈 중 하나로, 사전에 import한 뒤 sys에 포함된 객체들을 사용 가능하다.

sys는 System-Specific Parameters and Functions로, 파이썬에서 제공하는 모듈이다.
OS 모듈 안에 있으며, 파이썬 인터프리터가 제공하는 변수와 함수를 직접 제어할 수 있게 해주는 모듈로 C언어로 작성되어 있다.

이미 import된 모듈은 sys.modules를 통해 해당 모듈의 위치를 파악할 수 있으며, 이 기능을 통해 sys의 위치를 확인하면 다음과 같은 결과를 볼 수 있다.

즉, sys모듈은 built-in 모듈로써 Python 언어 자체에 포함되어있다.

built-in 모듈과 파이썬 표준 라이브러리는 다르다.
built-in 모듈과 파이썬 표준 라이브러리는 모두 파이썬 플랫폼에 기본적으로 내장되어있고 사전에 import 작업을 해야 사용할 수 있다는 공통점이 있지만,
파이썬 표준 라이브러리 중 built-in 모듈(ex. sys 등)은 파이썬 언어 자체에 포함되어 외부 탐색 없이 바로 import 되지만,
built-in이 아닌 표준 라이브러리들(ex. random 등)은 별도 파일 형태로 존재하여 외부 경로를 탐색하여 import된다.

Absolute Path 와 Relative Path의 차이점

파이썬에 기본적으로 내장된 표준 라이브러리나 pip를 통해 inatall된 라이브러리는 특별한 경로 설정 없이 import되지만, 자체적으로 만든 'local 패키지'의 경우 그렇지 않다. 따라서 경로를 지정해주어야 하는데, 그 방법에는 Absolute PathNative Path 두 가지가 있다.\

절대 경로(Absolute Path)

Path 경로의 시작점이 해당 프로젝트의 최상단에서 시작한다. 만약 아래와 같은 경로로 이루어진 프로젝트가 있다고 가정한다면,

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

Absolute Path의 시작 지점은 my_app이 되며, 아래와 같은 방식으로 모듈을 import할 수 있다.

from package1 import module1
from package2.subpackage1 import module5

# 모듈 내 객체만 import하는 경우
from package2.subpackage1.module5 import function1

Absolute Path는 경로를 명시적으로 지정하기 때문에 프로그램 작성에 안정적이고 가독성이 높아지지만, 코드가 너무 길어질 수 있다는 단점이 있다.

상대 경로(Relative Path)

Relative Path는 경로의 시작점이 프로젝트의 최상단이 아닌, import를 선언하는 파일의 현재 위치를 기준으로 한다. 따라서 최상단에서 하위 디렉터리로 따라가지 않아도 되므로 경로가 짧아질 수 있지만 상향으로 올라갔다가 다른 디렉터리로 내려가는 등 다소 복잡한 경로를 거칠 수 있다.

현재 디렉터리를 기준으로 활용할 때는 .을 사용하며, 이는 선언문이 담긴 파일의 현재 디렉터리를 의미한다. 상위 디렉터리를 기준으로 활용할 때는 ..을 사용한다. (추가 내용 참고)

메인 모듈에서의 import

메인모듈에서 상대 경로를 활용해서 모듈을 import할 경우, 위와같이 attempted relative import with no known parent package라는 오류가 발생한다.

상대 경로를 활용한 import는 현재 모듈의 이름을 기준으로 둔다. 하지만 메인 모듈의 이름은 항상 __main__이며, 메인 모듈로 사용되는 모듈들은 반드시 절대 경로를 활용한 import를 활용해야한다.

따라서 위 케이스의 오류의 경우 상대 경로 대신 절대 경로를 활용한 import 구문으로 수정한다면 오류를 피할 수 있다.

init.py의 역할

__init__.py는 해당 디렉터리가 패키지로 인식되도록 해주는 역할을 수행하며, 파이썬 3.3 이전 버전의 경우 해당 파일이 꼭 있어야 패키지로써 사용이 가능했다.

이후 버전에서는 __init__.py가 없더라도 패키지로써 활용이 가능

0개의 댓글