是有一个简单的方式列出名称的所有模块在一个软件包,而不使用 __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这仅适用于居住目的和模块列出仅仅是模块,进口之前。

清单模块在一个包看起来真容易使用 检查:

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

这是一种递归的版本,与python3.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")

如果你想看一个信息对你的包装以外的代码(从命令)可以使用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>

你会有同样的结果作为pydoc但内部的口译员使用的帮助

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

根据cdleary的例子,这里有一个递版本的路径为所有子模块:

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)

印dir(模块)

def package_contents(package_name):
  package = __import__(package_name)
  return [module_name for module_name in dir(package) if not module_name.startswith("__")]
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top