WeniVooks

검색

견고한 파이썬

모듈과 패키지 동작과 재사용

1. 모듈의 내부 동작 원리

pip install 명령어를 사용하면 PyPI로부터 패키지를 다운로드 받아 site-packages 디렉토리(Python311\Lib\site-packages, Lib 폴더 아래 있다는 것을 주의해주세요.)에 설치합니다. python3 -m site 명령어로 설치된 폴더를 확인할 수 있습니다.

python에서도 아래와 같이 모듈을 추가하여 sys.path 를 살펴볼 수 있습니다.

이렇게 설치된 모듈은 아래 명령어를 통해 확인할 수 있었습니다.

pip list
pip list
1.1 모듈의 로딩

Python에서 모듈은 아래와 같은 형태, import문을 통해 로드됩니다. 모듈이 처음 import 되었을 때, 그 모듈의 코드는 한 번만 실행되고, 그 결과 (함수나 클래스의 정의, 변수의 초기화 등)는 시스템의 모듈 테이블에 저장됩니다. 이후 동일한 모듈이 다시 import 되면, Python은 새로이 코드를 실행하는 대신 모듈 테이블에서 모듈의 상태를 불러옵니다.

import pandas as pd
import pandas as pd
1.2 import 문의 내부 동작
  1. Python은 먼저 sys.modules를 체크(Python이 실행될 때 자동으로 로드)합니다. 이 딕셔너리는 이미 로드된 모듈들의 이름을 키로 하고, 해당 모듈 객체를 값으로 가집니다. 모듈이 이미 sys.modules에 존재한다면, 그것이 반환됩니다.

  2. sys.modules에 없다면, Python은 sys.path에 있는 디렉토리들을 순회하면서 모듈이 있는지 찾습니다. sys.path는 Python 인터프리터에서 모듈을 어디에서 찾아야 할지 알려주는 경로의 리스트입니다. 이 리스트는 다음과 같은 위치를 포함합니다.

    1. 스크립트가 실행되는 현재 디렉토리 (또는 Python 인터랙티브 세션을 시작한 디렉토리)

    2. PYTHONPATH 환경 변수에 명시된 모든 디렉토리 (환경 변수가 설정된 경우, window의 환경변수 설정하기로 검색하시면 됩니다.)

    3. Python 설치 시 지정된 라이브러리 디렉토리, 기본적으로 Windows에서는 "C:\PythonXX\Lib"와 같은 형태로 될 것입니다. 여기서 'XX'는 Python의 버전을 나타냅니다.

    4. 각각의 .egg 파일 (있을 경우)

      EGG 파일 형식 - Python 배포 파일
    5. sys.path에 디렉토리를 동적으로 추가한 경우. 예를 들어, 스크립트에서 다른 디렉토리에 있는 모듈을 임포트하려는 경우, sys.path.append('/path/to/directory')를 사용하여 해당 디렉토리를 sys.path에 추가할 수 있습니다. 그러면 Python은 그 디렉토리를 검색하여 모듈을 찾을 수 있습니다.

    6. site-packages.pth 파일을 참고합니다.

  3. Python이 모듈을 찾았다면, 모듈의 코드를 읽고 실행합니다. 모듈의 이름이 sys.modules에 추가되고, 이 이름으로 모듈을 참조할 수 있습니다.

    1. 실습 1 : 아래와 같이 모듈을 만들고, sys.modules에 포함이 되었는지 확인해보세요.

      # sampletest.py
      name = 'hojun'
      # sampletest.py
      name = 'hojun'
      # colab
      import sampletest
       
      sampletest.name
      # colab
      import sampletest
       
      sampletest.name
      # colab
      import sys
       
      'sampletest' in sys.modules # True
      # colab
      import sys
       
      'sampletest' in sys.modules # True
    2. 실습 2 : colab에서 /content/a/b/c의 폴더를 만들어 거기서 모듈 검색이 가능하게 해주세요. a/b/c 폴더 안에는 sampletest 파일이 들어 있습니다. 실행하기 전 런타임을 초기화 해주세요.

      import sampletest
       
      sampletest.name # Error
      import sampletest
       
      sampletest.name # Error
      import sys
       
      'sampletest' in sys.modules # False
      import sys
       
      'sampletest' in sys.modules # False
      sys.path.append('/content/a/b/c')
      sys.path.append('/content/a/b/c')
      import sampletest
       
      sampletest.name
      import sampletest
       
      sampletest.name
      import sys
       
      'sampletest' in sys.modules # False
      import sys
       
      'sampletest' in sys.modules # False
  4. 만약 Python이 모듈을 찾지 못했다면, ModuleNotFoundError가 발생합니다.

1.3 모듈의 실행

모듈이 로드되면, 모듈의 코드는 최상위 레벨에서 실행되고, 모듈의 네임스페이스를 정의하는데 사용되는 이름들은 생성됩니다. 모듈의 네임스페이스는 import 문을 통해 접근할 수 있습니다.

2. 모듈과 패키지의 재사용성

모듈과 패키지의 재사용성 이해하기

  1. 재사용성의 중요성

    • 코드의 재사용성을 높이는 것은 개발 시간을 줄이고, 코드의 품질을 향상시키는 데 중요합니다. 재사용성이 높은 코드는 수정이 용이하고, 에러를 줄일 수 있습니다.
    • Python의 모듈과 패키지 시스템은 코드의 재사용성을 크게 향상시킵니다.
  2. 모듈의 재사용성

    • 모듈은 Python 코드를 포함하는 .py 파일로, 함수, 변수, 클래스 등을 정의할 수 있습니다. 이렇게 정의된 모듈은 import문을 통해 다른 Python 코드에서 재사용할 수 있습니다.
    • 예를 들어, 특정 기능을 수행하는 함수를 여러 스크립트에서 사용해야 하는 경우, 이 함수를 모듈에 정의하고 필요한 스크립트에서 임포트하여 사용할 수 있습니다.
  3. 패키지의 재사용성

    • 패키지는 관련된 여러 모듈을 하나의 디렉토리에 모아놓은 것입니다. 패키지를 통해 모듈을 논리적으로 그룹화하고, 이를 재사용할 수 있습니다.

    • 예를 들어, 여러 모듈에서 공통으로 사용하는 클래스나 함수를 utilities라는 패키지에 모아놓고, 이 패키지를 임포트하여 코드를 재사용할 수 있습니다.

    • 실습

      먼저, utilities 패키지를 만들고, 이 안에 math_tools.py라는 모듈을 만들어 보겠습니다. 이 모듈에는 공통으로 사용할 수 있는 수학 함수들을 정의합니다.

      # utilities/math_tools.py
       
      def add(x, y):
          return x + y
       
      def subtract(x, y):
          return x - y
      # utilities/math_tools.py
       
      def add(x, y):
          return x + y
       
      def subtract(x, y):
          return x - y

      그 다음, 이 utilities 패키지를 다른 스크립트에서 임포트하여 함수를 사용하는 예제입니다.

      # main.py
       
      from utilities.math_tools import add, subtract
       
      def main():
          print(add(10, 5))  # 출력: 15
          print(subtract(10, 5))  # 출력: 5
       
      if __name__ == "__main__":
          main()
      # main.py
       
      from utilities.math_tools import add, subtract
       
      def main():
          print(add(10, 5))  # 출력: 15
          print(subtract(10, 5))  # 출력: 5
       
      if __name__ == "__main__":
          main()

      위 예제에서 main.py 스크립트는 utilities 패키지의 math_tools 모듈에서 addsubtract 함수를 임포트하여 사용하고 있습니다. 이렇게 패키지와 모듈을 사용하면, 공통 함수를 한 곳에 모아서 코드의 재사용성을 높일 수 있습니다.

{"packages":["numpy","pandas","matplotlib","lxml"]}
11.1 모듈과 패키지11.3 자주 사용되는 라이브러리