Computer >> 컴퓨터 >  >> 프로그래밍 >> Python

Python pkgutil 모듈 완벽 가이드 – 패키지 검색 경로 확장과 리소스 관리

특정 패키지의 모듈 검색 경로를 확장하거나, 패키지 내부에 함께 배포된 데이터 파일 같은 비코드(non-code) 리소스에 접근해야 할 때가 있습니다. 이럴 때 Python 표준 라이브러리의 pkgutil 모듈을 사용하면 됩니다.

pkgutil은 Python 패키지의 임포트(import) 규칙을 변경하거나 확장할 수 있는 다양한 함수를 제공하며, 패키지 안에 포함된 파일에서 코드가 아닌 리소스를 불러오는 기능도 지원합니다.

extend_path(path, name)

extend_path() 함수는 하나의 패키지를 구성하는 모듈들의 검색 경로를 확장해 줍니다. 기본적인 용도는 아래 코드처럼 패키지의 __init__.py 파일에 넣어두는 것입니다.

import pkgutil
__path__ = pkgutil.extend_path(__path__, __name__)

extend_path()는 두 번째 인자로 전달된 패키지 이름과 동일한 이름의 하위 디렉터리를 가진 디렉터리를 sys.path에서 찾아 스캔합니다. 그런 다음 발견된 디렉터리 목록을 첫 번째 인자로 전달된 기존 path 값과 결합하여, 패키지 임포트 경로로 바로 사용할 수 있는 단일 리스트를 반환합니다.

주요 함수 살펴보기

find_loader(fullname)

전달된 fullname(모듈 전체 이름)에 해당하는 모듈 로더(loader) 객체를 반환합니다. 참고로 이 함수는 최신 Python 버전에서 권장되지 않으며, importlib.util.find_spec() 사용이 권장됩니다.

get_importer(path_item)

주어진 path_item에 대한 파인더(finder) 객체를 반환합니다. 파인더는 해당 경로에서 모듈을 찾는 역할을 담당합니다.

get_loader(module_or_name)

module_or_name에 해당하는 로더 객체를 가져옵니다. 이 함수 역시 deprecated 상태이므로 새 코드에서는 importlib 계열 API를 사용하는 것이 좋습니다.

iter_importers(fullname='')

지정된 모듈 이름에 대해 파인더(finder) 객체들을 순차적으로 생성(yield)합니다.

iter_modules(path=None, prefix='')

path에 있는 모든 서브모듈에 대한 ModuleInfo를 생성합니다. path가 None이면 sys.path에 있는 모든 최상위(top-level) 모듈을 대상으로 합니다.

>>> pk = pkgutil.iter_modules()
>>> for p in pk:
    print(p[1])

위 예제를 실행하면 현재 환경에서 임포트 가능한 최상위 모듈들의 이름이 하나씩 출력됩니다.

walk_packages(path=None, prefix='', onerror=None)

iter_modules()와 유사하지만 재귀적으로 동작합니다. path 아래의 모든 모듈을 깊이 우선으로 탐색하며 ModuleInfo를 생성하고, path가 None이면 접근 가능한 모든 모듈을 대상으로 합니다.

다음은 특정 패키지와 그 하위 패키지들을 재귀적으로 탐색하는 예제입니다.

import pkgutil
import sys

def explore_package(module_name):
    loader = pkgutil.get_loader(module_name)
    for sub_module in pkgutil.walk_packages([loader.filename]):
        _, sub_module_name, _ = sub_module
        qname = module_name + "." + sub_module_name
        print(qname)
        explore_package(qname)

ModuleInfo namedtuple

ModuleInfo(module_finder, name, ispkg)는 모듈에 대한 간략한 요약 정보를 담고 있는 namedtuple입니다. 각 필드는 다음과 같습니다.

  • module_finder: 해당 모듈을 찾은 파인더 객체
  • name: 모듈의 이름
  • ispkg: 모듈이 패키지인 경우 True, 일반 모듈인 경우 False

이처럼 pkgutil 모듈을 활용하면 패키지 구조를 동적으로 탐색하고, 검색 경로를 유연하게 확장할 수 있어 플러그인 시스템이나 자동화 도구를 개발할 때 특히 유용합니다.