【发布时间】:2016-02-14 23:38:41
【问题描述】:
我正在尝试在运行时动态导入与模式匹配的 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 上它根本找不到任何模块。如果我在函数load_modules_from_dir 中打印dirname,我得到: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。
【问题讨论】:
-
盯着
'\t'不会给你任何警报? -
@eryksun 是的,你是对的。如果我用
\\t替换\t,它也适用于Python shell。但你让我思考。os.path.join()返回的路径必须已经包含路径的转义版本。当我在函数load_modules_from_dir中打印参数dirname时,我得到:H:\temp\linx\dist\calibrate\dcljscal而不是H: emp\linx\dist\calibrate\dcljscal。现在的问题是为什么它在pkgutil.iter_modules()中不起作用? -
os.path.join(os.path.dirname(__file__))没有意义。使用os.path.abspath(os.path.dirname(__file__))。 -
@eryksun
os.path.join()和os.path.abspath()在我的系统上给出相同的结果。谢谢你的帮助。你用\t为我指明了正确的方向。 -
是的,但是加入一个字符串的路径来创建绝对路径并不是
os.path.join的预期效果。使用显然是为你想做的事情而设计的功能。不要依赖无关函数的副作用。
标签: python windows python-2.7 path-separator