0

我正在尝试在运行时动态导入与模式匹配的 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如果我在 function中打印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。

4

1 回答 1

0

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

有很多 SE 帖子试图给出解决方案。他们中的大多数修复了一个特殊情况,一般不工作。关于什么是最好的方法没有达成共识。请参阅:
- windows 中 os.path.join 的不可预测结果
- Python windows 路径斜杠
- Python 3 中的路径分隔符
- python 中的 Windows 路径
- windows 上 os.path.join 的混合斜杠
-为什么 os.path.join 不使用 os .path.sep 还是 os.sep?

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

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

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

于 2016-02-15T19:14:05.723 回答