如何找到给定Python发行版提供的模块?

2024-06-26 09:42:05 发布

您现在位置:Python中文网/ 问答频道 /正文

Python需要一个由一系列模块组成的列表要求.txt文件。首先安装配电盘,以便在当地进行检查。在

看起来我应该能够使用pip.req.parse_requirements从需求文件中获取发行版列表。从那里,我如何找到发行版提供的模块的名称?在


Tags: 模块pip文件txt名称列表parsereq
2条回答

如果python版本是2.3+的话,您可能可以使用内置的pkgutil模块

例如

import sys, pkgutil
mods = set()

#You may not need this part if you don't care about the builtin modules
print sys.builtin_module_names
for m in sys.builtin_module_names:
    if m != '__main__':
        mods.add(m)
        #mods.add(m)


for loader, name, ispkg in pkgutil.walk_packages():
    if name.find('.') == -1:
        mods.add(name)

print mods

正如您所说,由于发行版不是它们包含的模块,所以我们遇到了一个问题:发行版的典型安装过程是下载、解包,然后运行设置.py,它处理安装过程的其余部分。在

结果是,即使给定了Python发行版,您也不能真正知道是什么设置.py不用运行也行。可能会有一些惯例,你可能会从中找出很多信息,做出很多好的猜测,但是运行这些设置.py'文件实际上是查看它实际安装到站点包中的内容的唯一方法。因此,parse_requirements,或者实际上任何pip内部构件都不会对您有用,除非您只对发行版感兴趣。在

因此,尽管如此,我认为解决问题的最佳方法是:

  1. 设置不带站点包的虚拟环境
  2. pip -r requirements.txt来实际安装所有包
  3. sys.path中搜索.py、.pyc并放入__init__.py?文件的子文件夹中,以构建模块列表。在
  4. 杀了那个虚拟人然后继续前进。在

我不确定第三步在其他更好的方面是否可行。此外,您仍然有可能丢失动态创建的模块或其他棘手的问题,但这应该会捕获大部分模块。在

编辑:

这里有一些代码应该适用于除zip文件以外的所有文件:

import sys, os

def walk_modules_os(root):
    def inner_walk(dir_path, mod_path):
        filelist = os.listdir(dir_path)
        pyfiles = set()
        dirs = []
        for name in filelist:
            if os.path.isdir(os.path.join(dir_path, name)):
                dirs.append(name)
            else:
                pre, ext = os.path.splitext(name)
                if ext in ('.py', '.pyc', '.pyo'):
                    pyfiles.add(pre)

        if len(mod_path):
            if '__init__' not in pyfiles:
                return
            pyfiles.remove('__init__')
            yield mod_path

        for pyfile in pyfiles:
            yield mod_path + (pyfile,)

        for directory in dirs:
            sub = os.path.join(dir_path, directory)
            for mod in inner_walk(sub, mod_path + (directory,)):
                yield mod

    root = os.path.realpath(root)
    if not os.path.isdir(root):
        return iter([])
    return iter(inner_walk(root, tuple()))

# you could collect as a set of tuples and do set subtraction, too
for path in sys.path:
    for mod in walk_modules_os(path):
        print mod 

编辑2:

好吧,克里基。GWW有正确的想法。比我的好得多的解决办法。在

相关问题 更多 >