2012-08-15 65 views
2

Python导入。再次...导入错误 - 发生了什么?

我有这个文件的结构:

[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) 

我得到导入错误:

[email protected]:~/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 
[email protected]:~/projects/test$ 

我不明白:第一次from scripts import main工作(通过 “合作” 我的意思是它没有与ImportError失败),第二次相同的代码给出ImportError: cannot import name main

这是怎么回事?

更新:

我的问题不是关于循环进口。我很困惑的事实,即完全相同的代码from scripts import main第一次工作正常,然后第二次失败。

我想有一些内部导入机制,我不明白。

第一次语句导入模块,第二次完全相同的代码尝试从模块导入名称。这是如何工作的?

+0

我不是这个话题的专家,这是少了很好的答案,但这[链接](http://docs.python.org/dev/howto/pyporting.html#from-future-import-absolute-import)可能会帮助你。 – sfx 2012-08-15 17:59:27

回答

5

您创建了一个循环导入。你不能那样做。避免从install导入main

发生了什么事情是一个模块在导入时,在整个顶层被执行之前是不完整的。如果在执行期间它导入另一个模块(直接或间接)尝试再次导入原始模块,则这将失败。原始模块尚未完成导入。

换句话说,你要创建一个圆形图:

start -> scripts.main -> scripts.install 
      ^    | 
       |    | 
       ---------------- 

您需要重新安排你的代码,不需要从mainscripts包中导入。

请参阅What are the “best practices” for using import in a module?了解如何处理此问题的一些提示。

+0

我希望第二次像第一次那样工作,即导入'scripts.main'并将其分配给名称'main' – warvariuc 2012-08-15 17:54:48

+0

>原始模块还没有导入。<然而,它已经在'sys.modules',尽管它的导入没有完成 – warvariuc 2012-08-15 17:56:52

+0

是的,但它是*不完整*。 Python不能保证你试图导入的对象实际上会在那里或正确定义。 – 2012-08-15 17:58:56

0

这应该工作:

start.py:

from scripts import main 

脚本/ main.py:

import install 

脚本/安装。潘岳:

import main 
+0

这与我的情况不同。我尝试从一个包中导入一个模块,而不是从另一个模块的名称 – warvariuc 2012-08-15 18:06:43

+0

已更新的答案以解决您的问题 – Arseniy 2012-08-16 06:11:52

3

main进口installinstall进口main

  • start.pyfrom scripts import main导致
  • from . import installmain.py导致
  • from scripts import maininstall.py - 圆形进口

要解决循环导入要么将maininstall合并到单个模块中,要么创建两个模块都可以导入的第3个模块。

+0

请参阅我的更新 – warvariuc 2012-08-15 18:18:04

+0

@warwaruk:我已经明确说明了该序列。 '从脚本导入main' *不会*第一次工作,因为它从来没有完成首先。 – jfs 2012-08-15 18:28:19

0

这是一个补丁我用它来覆盖默认行为:

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