Python通配符导入与命名导入

Python通配符导入与命名导入,python,import,wildcard,named,Python,Import,Wildcard,Named,好的,我在我的一个项目中有一些非常奇怪的行为,我希望有人能告诉我为什么。我的文件结构如下所示: MainApp.py res/ __init__.py elements/ __init__.py MainFrame.py 在MainFrame.py内部,我定义了一个名为RPMWindow的类,它扩展了wx.Frame 在MainApp.py中,此操作有效: from res.elements.MainFrame import * 这并不是: from res.elem

好的,我在我的一个项目中有一些非常奇怪的行为,我希望有人能告诉我为什么。我的文件结构如下所示:

MainApp.py
res/
  __init__.py
  elements/
    __init__.py
    MainFrame.py
在MainFrame.py内部,我定义了一个名为RPMWindow的类,它扩展了wx.Frame

在MainApp.py中,此操作有效:

from res.elements.MainFrame import *
这并不是:

from res.elements.MainFrame import RPMWindow
我意识到通配符导入不会造成任何伤害,但我更感兴趣的是理解当通配符成功时,命名导入为什么会失败

使用类名时,我得到以下回溯:

Traceback (most recent call last):
  File "C:\myApps\eclipse\plugins\org.python.pydev.debug_1.5.6.2010033101\pysrc\pydevd.py", line 953, in <module>
    debugger.run(setup['file'], None, None)
  File "C:\myApps\eclipse\plugins\org.python.pydev.debug_1.5.6.2010033101\pysrc\pydevd.py", line 780, in run
    execfile(file, globals, locals) #execute the script
  File "C:\Documents and Settings\Daniel\workspace\RPM UI - V2\src\MainApp.py", line 2, in <module>
    from res.elements.MainFrame import RPMWindow
  File "C:\Documents and Settings\Daniel\workspace\RPM UI - V2\src\res\elements\MainFrame.py", line 2, in <module>
    from res.elements.MenuBar import MenuBarBuilder
  File "C:\Documents and Settings\Daniel\workspace\RPM UI - V2\src\res\elements\MenuBar.py", line 2, in <module>
    from MainApp import _, DataCache
  File "C:\Documents and Settings\Daniel\workspace\RPM UI - V2\src\MainApp.py", line 2, in <module>
    from res.elements.MainFrame import RPMWindow
ImportError: cannot import name RPMWindow
回溯(最近一次呼叫最后一次):
文件“C:\myApps\eclipse\plugins\org.python.pydev.debug_1.5.6.2010033101\pysrc\pydevd.py”,第953行,在
运行(安装程序['file'],无,无)
文件“C:\myApps\eclipse\plugins\org.python.pydev.debug_1.5.6.2010033101\pysrc\pydevd.py”,第780行,正在运行
execfile(文件、全局、局部)#执行脚本
文件“C:\Documents and Settings\Daniel\workspace\RPM UI-V2\src\MainApp.py”,第2行,在
从res.elements.MainFrame导入RPMWindow
文件“C:\Documents and Settings\Daniel\workspace\RPM UI-V2\src\res\elements\MainFrame.py”,第2行,在
从res.elements.MenuBar导入MenuBarBuilder
文件“C:\Documents and Settings\Daniel\workspace\RPM UI-V2\src\res\elements\MenuBar.py”,第2行,在
从MainApp导入,数据缓存
文件“C:\Documents and Settings\Daniel\workspace\RPM UI-V2\src\MainApp.py”,第2行,在
从res.elements.MainFrame导入RPMWindow
导入错误:无法导入名称RPMWindow

使用通配符导入时,我不会收到回溯,我的应用程序会打开。

您有循环导入:


MainFrame.py间接导入MainApp.py,MainApp.py导入MainFrame.py。因此,当MainApp.py导入MainFrame.py时,RPMWindow类尚未定义,您将获得ImportError。

我没有时间研究通配符为什么对您有效,但我可以说,您的直接名称导入失败是因为您的代码中有一个导入周期:


您正在尝试导入
res.elements.MainFrame
,但该代码的一部分正在尝试导入
res.elements.MenuBar
,它再次尝试导入
res.elements.MainFrame
。现在,您第一次尝试导入
res.elements.MainFrame
尚未完成,请重试。

您的代码中有循环导入:同一个模块是某个其他模块所必需的,并且需要使用该模块,当您这样想时,它显然是不可靠的。大多数问题都可以通过使用
import a
并在以后参考
a.b
来解决,而不是从import b或从import*引用

特别是,切勿从导入中使用
*
。通配符导入会使名称空间变得混乱,使代码不易维护、可读、理智和可预测。
导入
和导入*
中的
之间的区别在于将一个盒子拖进一个房间和将里面的东西倒满地板之间的区别


如果您可以将共享代码转移到它自己的模块中,或者以某种方式重构出循环导入的需求,那就更好了。循环导入总是表明存在设计问题。

您能否提供使用命名导入时得到的实际回溯?请指出“这不起作用”的含义。在第一个案例中,您是否真的导入了RPMWindow?正如您所指出的,我发现了这一点。我想我已经解决了。谢谢