import - 在 python 3中,动态导入+ 相对导入

  显示原文与译文双语对照的内容
0 0

我有一个 python 3 项目,我使用 imp.load_module 从磁盘动态导入模块。 但是,我遇到了 relative 导入失败的问题,当 relative 导入发生在动态导入的模块中时。

从我所读的内容来看,在确定导入路径的路径时,只使用 __file____path____package____name__ 。 但是,我已经在代码 below 中验证了这些,并且在动态导入时仍然失败。 ( 当在解释器中使用更新的sys.path 导入时)


# File structure:
# [root]
# ├─ __init__.py
# ├─ board.py
# └─ test.py


# Contents of 'board.py':
import os, sys
import root # Already imported... just need a reference

ROOT_DIR = os.path.dirname(root.__file__)
assert root is sys.modules['root']
assert root.__package__ is None
assert root.__name__ == 'root'
assert root.__file__ == os.path.join(ROOT_DIR, '__init__.py')
assert not hasattr(root, '__path__')

xx = object()
assert xx is sys.modules['root.board'].xx
assert __package__ is None
assert __name__ == 'root.board'
assert __file__ == os.path.join(ROOT_DIR, 'board.py')
assert not hasattr(sys.modules['root.board'], '__path__')

assert os.path.isfile(os.path.join(ROOT_DIR, 'test.py'))
from. import test # ImportError('cannot import name test',)

但是,如果在导入失败之前 hack sys.path 和重新导入当前软件包,它将运行:


oldroot = root
del sys.modules['root']
sys.path.append(os.path.dirname(ROOT_DIR))
import root
from. import test # No error here

并进一步,四金属性提到 上面 是相同的在新老包装:


assert oldroot.__package__ == root.__package__
assert oldroot.__name__ == root.__name__
assert oldroot.__file__ == root.__file__
assert not hasattr(root, '__path__')

这意味着 __package____name____file____path__ 不能是完整的故事。 python 还使用其他属性来定位导入? 我忽略了什么会导致导入失败?

时间: 原作者:

0 0

缺少 root.__path__ 值是可疑的( 这意味着 python 不认为 root 是一个包) 。

这两个 load_module() 调用都是用 1 ( 模块)的类型值进行的,而不是第一个类型的5 ( 软件包) 也很不清楚。

你是否使用 imp.find_module() 来计算 imp.load_module() 调用的正确输入?

对于软件包,imp.load_module()的输入应该类似于下面这样:


# demo is a package in the current directory for this example
>>> info = imp.find_module('demo')
>>> info
(None, 'demo', ('', '', 5))
>>> demo = imp.load_module('demo', *info)
>>> demo.__path__
['demo']

原作者:
...