4

好的,我的一个项目中有一些相当奇怪的行为,我希望有人能告诉我原因。我的文件结构如下所示:

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

使用通配符导入时,我没有收到回溯并且我的应用程序打开。

4

3 回答 3

8

您有循环导入:

MainFrame.py 是间接导入 MainApp.py,MainApp.py 是导入 MainFrame.py。结果,当 MainApp.py 导入 MainFrame.py 时,RPMWindow 类尚未定义,您会收到 ImportError。

于 2010-04-19T18:02:45.343 回答
0

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

您正在尝试 import res.elements.MainFrame,但代码的一部分正在尝试 importres.elements.MenuBar尝试res.elements.MainFrame再次导入。IOW,在您再次尝试之前,您的第一次导入尝试res.elements.MainFrame尚未完成。

于 2010-04-19T18:07:09.437 回答
0

您的代码中有循环导入:同一个模块既需要也需要使用某个其他模块,当您这样想时,它显然是不稳定的。大多数问题可以通过使用import a和稍后引用a.b 而不是from a import b或来解决from a import *

特别是,永远不要使用from a import *. 通配符导入会使您的命名空间变得混乱,并使您的代码难以维护、可读、健全和可预测。import a和之间from a import *的区别是将盒子拖入房间并将其内容倒在地板上的区别。

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

于 2010-04-19T18:07:34.387 回答