Import error - what is going on?
python导入。再一次。。。
我有这个文件结构:
1 2 3 4 5 6 | [test] start.py (from scripts import main) [scripts] __init__.py (empty) main.py (from . import install) install.py (from scripts import main # or # from . import main) |
我收到导入错误:
1 2 3 4 5 6 7 8 9 10 | vic@wic:~/projects/test$ python3 start.py Traceback (most recent call last): File"start.py", line 2, in <module> from scripts import main File"/home/vic/projects/test/scripts/main.py", line 1, in <module> from . import install File"/home/vic/projects/test/scripts/install.py", line 1, in <module> from scripts import main ImportError: cannot import name main vic@wic:~/projects/test$ |
我不明白:第一次
怎么回事?
更新:
我的问题不是关于循环进口。我被这样一个事实搞糊涂了:完全相同的代码
我想有一些我不理解的内部导入机制。
第一次语句导入模块时,第二次完全相同的代码尝试从模块导入名称。这是怎么运作的?
您创建了循环导入。你不能那样做。避免从
所发生的是,在导入模块时,在执行整个顶层之前,模块是不完整的。如果在执行过程中,它导入了另一个试图(直接或间接)再次导入原始模块的模块,则此操作将失败。原始模块尚未完成导入。
换句话说,您正在创建一个圆形图形:
1 2 3 4 | start -> scripts.main -> scripts.install ^ | | | ---------------- |
您需要重新安排您的代码,使其不需要从您的
了解在模块中使用导入的"最佳实践"是什么?有关如何处理此问题的一些提示。
start.py 中的from scripts import main 导致main.py 中的from . import install 导致install.py 中的from scripts import main ——循环进口
为了解决循环导入问题,可以将
这是我用来覆盖默认行为的修补程序:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | import sys import builtins import importlib def _import(name, globals=None, locals=None, fromlist=None, level=0, __import__=__import__): """A hack to to make names of imported modules to be available in the parent package before they are fully imported. If a module is present in sys.modules event if it's not fully imported, it should not be a problem. I.e. ``from package import module1, module2`` will create variables ``package.module1`` and ``package.module2`` at start of the import, not when it's finished. This helps in some situations with circular import. """ module = __import__(name, globals, locals, fromlist, level) for attr in fromlist or (): sub_module = sys.modules.get(module.__name__ + '.' + attr) if sub_module: # is this a module? # if subpackage is already being imported, even if not finished, # inject its name into the parent package setattr(module, attr, sub_module) return module builtins.__import__ = _import |
下面是一个测试这个的项目:https://github.com/warvariuc/python_import_improver
这应该有效:
PY:
1 | from scripts import main |
脚本/main.py:
1 | import install |
脚本/install.py:
1 | import main |