替代品imp.find_模块?

2024-10-16 20:44:41 发布

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

背景

我已经厌倦了pylint在使用命名空间包和将代码库划分为单独文件夹时无法导入文件的问题。因此,我开始深入研究astNG源代码,它已经被确定为问题的根源(参见astNG上的bugreport8796)。问题的核心似乎是在寻找进口品的过程中使用Python自己的imp.find_module。在

结果是导入的第一个(子)包import a.b.c中的a通过None路径被送入find_module。不管返回的路径是什么,都会被送入find_module查找循环中的下一个过程,在上一个例子中,您可以在这里找到b。在

伪代码来自logilab.common.modutils公司名称:

path = None
while import_as_list:
      try:
           _, found_path, etc = find_module(import_as_list[0], path)
      #exception handling and checking for a better version in the .egg files
      path = [found_path]
      import_as_list.pop(0)

问题

这就是问题所在:你只能从find_module中获得第一个最佳点击,它可能包含也可能没有你的子包。如果你找不到这些子包,你就没有办法退出去尝试下一个。在

我试图明确地使用系统路径而不是None,这样就可以从路径列表中删除结果,然后再尝试一次,但是python的module finder非常聪明,不必在路径中进行完全匹配,这使得这种方法无法使用——据我所知。在

泪汪汪的恳求

是否有其他方法可以找到将返回所有可能匹配项或排除列表的模块?我也愿意接受完全不同的解决方案。最好不要手工修补python,但这不是不可能的,至少对于本地解决方案来说是这样。在

(注意:我正在运行Python2.6,由于当前公司政策无法升级,对p3k等的建议不会被标记为接受,除非这是唯一的答案。)


Tags: path方法代码import路径none列表过程
3条回答

警告+免责声明:尚未测试!在

在此之前:

for part in parts:
    modpath.append(part)
    curname = '.'.join(modpath)
    # ...
    if module is None:
        mp_file, mp_filename, mp_desc = imp.find_module(part, path)
        module = imp.load_module(curname, mp_file, mp_filename, mp_desc)

之后:-谢谢你提到^{}

^{pr2}$

从Python2.5开始,正确的方法是使用pkgutil.iter_modules()(对于平面列表)或{a2}(对于子包树)。两者都与命名空间包完全兼容。在

例如,如果我只想找到“jmb”的子包/子模块,我会:

import jmb, pkgutil
for (module_loader, name, ispkg) in pkgutil.iter_modules(jmb.__path__, 'jmb.'):
    # 'name' will be 'jmb.foo', 'jmb.bar', etc.
    # 'ispkg' will be true if 'jmb.foo' is a package, false if it's a module

您也可以使用iter_模块或walk_包来遍历所有上的模块搜索路径;详见以上链接文档。在

我也厌倦了派林的这种限制。在

我不知道有什么替代品imp.find_模块(),但我想我找到了另一种方法来处理PyLint中的命名空间包。查看我对你链接到的bug报告的评论(http://www.logilab.org/ticket/8796). 在

其思想是使用pkg_资源来查找名称空间包。这是我对logilab.common.modutils._module_file()的补充,就在while modpath之后:

  while modpath:
      if modpath[0] in pkg_resources._namespace_packages and len(modpath) > 1:
          module = sys.modules[modpath.pop(0)]
          path = module.__path__

不过,这不是很完善,只处理顶级命名空间包。在

相关问题 更多 >