Windows上的pkgutil.iter_modules()路径问题

时间:2016-02-14 23:38:41

标签: python windows python-2.7 path-separator

我正在尝试动态导入与运行时模式匹配的Python模块。这些模块位于Python包中。

我用来查找模块的函数是:

def load_modules_from_dir(dirname, pattern=""):
    modules = []
    for importer, package_name, _ in pkgutil.iter_modules([dirname]):
        if re.search(pattern, package_name):
            full_package_name = '%s.%s' % (dirname, package_name)
            if full_package_name not in sys.modules:
                module = importer.find_module(package_name).load_module(full_package_name)
                modules.append(module)
    return modules

我称之为:

module_dir = os.path.join(os.path.dirname(__file__))
modules = utils.load_modules_from_dir(module_dir, "jscal$")

在Linux上它找到所有模块,但在Windows上它根本找不到任何模块。如果我在功能dirname中打印load_modules_from_dir,我会得到:H:\temp\linx\dist\calibrate\dcljscal

我在Windows上的Python shell中将其复制并将其钉在路径分隔符上。以下找不到任何内容:

>>> for x in pkgutil.iter_modules(['H:\temp\linx\dist\calibrate\dcljscal']):print x
...
>>> 

如果我用Linux替换Windows路径分隔符,它可以工作:

>>> for x in pkgutil.iter_modules(['H:/temp/linx/dist/calibrate/dcljscal']):print x
...
(<pkgutil.ImpImporter instance at 0x00AD9C60>, 'demojscal', True)
(<pkgutil.ImpImporter instance at 0x00AD9C60>, 'dx2cremjscal', True)
(<pkgutil.ImpImporter instance at 0x00AD9C60>, 'linxjscal', True)
>>>

如果我用\替换\\,基本上转义Windows路径分隔符,它也有效:

>>> for x in pkgutil.iter_modules(['H:\\temp\\linx\\dist\\calibrate\\dcljscal']):print x
...
(<pkgutil.ImpImporter instance at 0x00AD9E68>, 'demojscal', True)
(<pkgutil.ImpImporter instance at 0x00AD9E68>, 'dx2cremjscal', True)
(<pkgutil.ImpImporter instance at 0x00AD9E68>, 'linxjscal', True)
>>>

似乎os.path.join(os.path.dirname(__file__))生成的路径不可移植 我希望os.path.join()会给我一条正确的路径,我可以在pkgutil.iter_modules()中不加改变地使用它。我在这里做错了什么?

我在Windows XP上使用Python 2.7.11。

1 个答案:

答案 0 :(得分:0)

简短的回答是:这个问题没有答案。表示路径名的字符串总是包含可以随时咬你的特殊字符。

有很多SE帖子试图提供解决方案。他们中的大多数修复了一个特殊情况,并且一般不起作用。关于最佳方法是什么没有达成共识。请参阅:
- Unpredictable results from os.path.join in windows
- Python windows path slash
- Path Separator in Python 3
- Windows path in python
- mixed slashes with os.path.join on windows
- Why not os.path.join use os.path.sep or os.sep?

这篇博客文章也值得一提,因为作者使用了一种稍微不同的方法来表达他的观点:backslashes-in-windows-filenames

处理路径名的一种实用方法是将Windows路径分隔符替换为Linux路径分隔符:path_name = path_name.replace('\\', '/')
Windows XP及更高版本Windows上的Python对C:/tab/newline/return/012/x012没有问题。

只有在必须打印或记录路径时,才能使用os.path.normpath()将路径转换为运行Python的操作系统或平台的表示形式。