program story

패키지에있는 Python 모듈의 이름을 나열하는 표준 방법이 있습니까?

inputbox 2020. 9. 11. 07:58
반응형

패키지에있는 Python 모듈의 이름을 나열하는 표준 방법이 있습니까?


사용하지 않고 패키지의 모든 모듈 이름을 나열하는 간단한 방법이 __all__있습니까?

예를 들어 다음 패키지가 제공됩니다.

/testpkg
/testpkg/__init__.py
/testpkg/modulea.py
/testpkg/moduleb.py

다음과 같은 작업을 수행하는 표준 또는 기본 제공 방법이 있는지 궁금합니다.

>>> package_contents("testpkg")
['modulea', 'moduleb']

수동 접근 방식은 패키지의 디렉토리를 찾기 위해 모듈 검색 경로를 반복하는 것입니다. 그런 다음 해당 디렉토리의 모든 파일을 나열하고 고유 이름이 지정된 py / pyc / pyo 파일을 필터링하고 확장자를 제거하고 해당 목록을 반환 할 수 있습니다. 그러나 이것은 모듈 가져 오기 메커니즘이 이미 내부적으로 수행하고있는 작업에 상당한 양의 작업처럼 보입니다. 그 기능이 어디에나 노출되어 있습니까?


아마도 이것이 당신이 찾고있는 것을 할 것입니까?

import imp
import os
MODULE_EXTENSIONS = ('.py', '.pyc', '.pyo')

def package_contents(package_name):
    file, pathname, description = imp.find_module(package_name)
    if file:
        raise ImportError('Not a package: %r', package_name)
    # Use a set because some may be both source and compiled.
    return set([os.path.splitext(module)[0]
        for module in os.listdir(pathname)
        if module.endswith(MODULE_EXTENSIONS)])

사용 python2.3를 이상 , 당신은 또한 사용할 수있는 pkgutil모듈을 :

>>> import pkgutil
>>> [name for _, name, _ in pkgutil.iter_modules(['testpkg'])]
['modulea', 'moduleb']

편집 : 매개 변수는 모듈 목록이 아니라 경로 목록이므로 다음과 같이 할 수 있습니다.

>>> import os.path, pkgutil
>>> import testpkg
>>> pkgpath = os.path.dirname(testpkg.__file__)
>>> print [name for _, name, _ in pkgutil.iter_modules([pkgpath])]

import module
help(module)

내가 뭔가를 간과하고 있는지 또는 답변이 오래된 것인지는 모르겠지만;

user815423426이 언급했듯이 이것은 라이브 객체에 대해서만 작동하며 나열된 모듈은 이전에 가져온 모듈 일뿐입니다.

inspect를 사용하면 패키지의 모듈을 나열하는 것이 정말 쉬워 보입니다 .

>>> import inspect, testpkg
>>> inspect.getmembers(testpkg, inspect.ismodule)
['modulea', 'moduleb']

이것은 파이썬 3.6 이상에서 작동하는 재귀 버전입니다.

import importlib.util
from pathlib import Path
import os
MODULE_EXTENSIONS = '.py'

def package_contents(package_name):
    spec = importlib.util.find_spec(package_name)
    if spec is None:
        return set()

    pathname = Path(spec.origin).parent
    ret = set()
    with os.scandir(pathname) as entries:
        for entry in entries:
            if entry.name.startswith('__'):
                continue
            current = '.'.join((package_name, entry.name.partition('.')[0]))
            if entry.is_file():
                if entry.name.endswith(MODULE_EXTENSIONS):
                    ret.add(current)
            elif entry.is_dir():
                ret.add(current)
                ret |= package_contents(current)


    return ret

모듈이 나열되어야합니다.

help("modules")

명령 프롬프트에서 Python 코드 외부에서 패키지에 대한 정보를 보려면 pydoc을 사용할 수 있습니다.

# get a full list of packages that you have installed on you machine
$ python -m pydoc modules

# get information about a specific package
$ python -m pydoc <your package>

You will have the same result as pydoc but inside of interpreter using help

>>> import <my package>
>>> help(<my package>)

Based on cdleary's example, here's a recursive version listing path for all submodules:

import imp, os

def iter_submodules(package):
    file, pathname, description = imp.find_module(package)
    for dirpath, _, filenames in os.walk(pathname):
        for  filename in filenames:
            if os.path.splitext(filename)[1] == ".py":
                yield os.path.join(dirpath, filename)

print dir(module)


def package_contents(package_name):
  package = __import__(package_name)
  return [module_name for module_name in dir(package) if not module_name.startswith("__")]

참고URL : https://stackoverflow.com/questions/487971/is-there-a-standard-way-to-list-names-of-python-modules-in-a-package

반응형