views:

241

answers:

3

Ok, I have some rather odd behavior in one of my Projects and I'm hoping someone can tell me why. My file structure looks like this:

MainApp.py
res/
  __init__.py
  elements/
    __init__.py
    MainFrame.py

Inside of MainFrame.py I've defined a class named RPMWindow which extends wx.Frame.

In MainApp.py this works:

from res.elements.MainFrame import *

And this does not:

from res.elements.MainFrame import RPMWindow

I realize that the wild card import won't hurt anything, but I'm more interested in understanding why the named import is failing when the wild card succeeds.

When using the class name I get this traceback:

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

When using the wild card import I don't receive a traceback and my application opens.

+7  A: 

You have circular imports:

MainFrame.py is indirectly importing MainApp.py, and MainApp.py is importing MainFrame.py. As a result, when MainApp.py is importing MainFrame.py, the RPMWindow class hasn't been defined yet and you get the ImportError.

interjay
I found this as you pointed it out. I think I've got it resolved. Thanks.
Dan
Casual reminder why circular imports are not a good habit!
jathanism
A: 

i don't have time to look into why the wildcard is working for you, but what i can say about your failure with the direct name import is that you have an import cycle in your code:

you are trying to import res.elements.MainFrame, but part of that code is trying to import res.elements.MenuBar which tries to import res.elements.MainFrame again. IOW, your first attempt to import res.elements.MainFrame has not completed yet before you try it again.

wescpy
+1  A: 

You have circular imports in your code: the same module is both required by and requires the use of a certain other module, which when you think of it like that, it clearly precarious. Most of the problems can be cleared up by using import a and later referring to a.b instead of from a import b or from a import *.

In particular, never use from a import *. Wildcard imports clutter your namespace and makes your code less maintainable, readable, sane, and predictable. The difference between import a and from a import * is the difference between dragging a box into a room and pouring its contents all over the floor.

It would be better if you could move shared code off to its own module or somehow refactor out the need for a circular import. Circular imports always indicate a design problem.

Mike Graham