Module import problems

Discussion in 'Python' started by simo, Apr 5, 2004.

  1. simo

    simo Guest

    I've written a pretty big wxPython script, and I thought I'd split the
    source into a few files.

    I'm going to have a main.py file which includes global defs, wxApp
    initialisation code, mainWindow() etc. and then each file will include
    a GUI class (which just happen to be a wxNotebook tab each).

    I'm having trouble accessing the imported classes though.

    For example I have login.py which contains something like this:

    class login(wx.Dialog):
    """create a login dialog box"""
    def __init__(self):
    wx.Dialog.__init__(self, None, -1, "Login")

    # create grid sizer
    self.grid_sizer = wx.GridSizer(3, 2, 2, 2)

    Then main.py contains something like this:

    import login

    class MyApp(wx.App):
    """define main wx app class"""
    def OnInit(self):
    login_frame = login()
    login_frame.Show(1)
    return True

    # call the main class
    app = MyApp(0)
    app.MainLoop()

    The problem is, that when I run main.py, I cannot seem to import login
    as a class - I keep getting 'module' object not callable.

    I tried login.login() to not call the module, but the class of the
    module, but that doesn't work either, I get 'module' object has no
    attribute 'login'. I thought login.login() would look for the def
    'login' not the class anyway?

    So how do you import classes from other files in Python - I can only
    seem to get it to import defs using 'from login import *' (yuk) or
    'import login', but I need classes for wxPython.

    Am I looking at this wrong, it is a bit of a Perl approach? Should I
    be calling login.init() or something weird?

    I always seem to get this with Python, I do pretty well, then I try to
    tidy things up and it gets too fiddly, I guess I still haven't got my
    head around OOP....
     
    simo, Apr 5, 2004
    #1
    1. Advertising

  2. simo

    Peter Hansen Guest

    simo wrote:

    > I'm having trouble accessing the imported classes though.
    >
    > For example I have login.py which contains something like this:
    >
    > class login(wx.Dialog):

    ....
    >
    > Then main.py contains something like this:
    >
    > import login
    >
    > class MyApp(wx.App):
    > """define main wx app class"""
    > def OnInit(self):
    > login_frame = login()
    >
    > The problem is, that when I run main.py, I cannot seem to import login
    > as a class - I keep getting 'module' object not callable.
    >
    > I tried login.login() to not call the module, but the class of the
    > module, but that doesn't work either, I get 'module' object has no
    > attribute 'login'. I thought login.login() would look for the def
    > 'login' not the class anyway?


    login.login(), based on the precise code that you showed, appears
    to be the correct thing. I'm not actually trying to understand
    how your code works, mind you, just looking at it syntactically.

    If that's giving you the error you say it is, something else is
    amiss. Do you "shadow" the "login" that comes from the import
    statement with a function somewhere, or a method, in the class
    MyApp, which you didn't show? You should be able to use the
    interactive prompt to "import login" and "login.login" without
    getting any kind of "no attribute" error. If you can do that,
    clearly the problem is in the MyApp module. Otherwise you've
    got something wrong with login.py after all.

    -Peter
     
    Peter Hansen, Apr 5, 2004
    #2
    1. Advertising

  3. simo

    simo Guest

    login.login or login.login() don't work.

    I tried adding...

    def simon():
    print "hello"

    ....to the top of login.py (before the login class) and then calling
    login.simon() and that works - but then that's a def, not a class....

    So I think the login class is failing to initialise as it can't find
    the wx class imported in main.py, because if I run login.py then I get
    "...wx not defined" surely I don't have to import wx in every file
    (that doesn't work actually)?!

    This namespace crap is becomming an inconvenience - jees, do we have
    to make everything global?!

    Also, does IDLE cache the compiled Python or something, as sometimes
    when I change a file and save/run it in the shell, it doesn't change
    (I do delete the .pyc files) until I quit and reload IDLE?

    This is with Python 2.3.2/Solaris (ActiveState) and 2.3.3/Windows
    (python.org) and wxPython 2.4.2.4/2.5.1.5
     
    simo, Apr 5, 2004
    #3
  4. simo

    Peter Hansen Guest

    simo wrote:

    > So I think the login class is failing to initialise as it can't find
    > the wx class imported in main.py, because if I run login.py then I get
    > "...wx not defined" surely I don't have to import wx in every file
    > (that doesn't work actually)?!


    Yes, of course you do.

    > This namespace crap is becomming an inconvenience - jees, do we have
    > to make everything global?!


    Really, it's not at all that difficult. Anyway, the namespaces are
    there to protect you and simplify the code. Although you could think
    of it as a small inconvenience to have to put imports for various
    things wherever you need them, the alternative is vastly more of a
    problem.

    > Also, does IDLE cache the compiled Python or something, as sometimes
    > when I change a file and save/run it in the shell, it doesn't change
    > (I do delete the .pyc files) until I quit and reload IDLE?


    I never use IDLE, so I can't say. My preferred approach is simply
    running things from the command line (but you get that way when you
    start focusing on unit testing rather than code-and-fix...).

    -Peter
     
    Peter Hansen, Apr 5, 2004
    #4
  5. simo

    simo Guest

    Yay, I've done it!

    I had to resort to "from login import *" in main.py and then "import
    wx" (and other modules like urllib/webbrowser etc) in login.py and it
    all seems to work.

    I didn't occur to me that I'd have to import the modules used in each
    module file, I thought it would work just from the parent (main.py)
    file.

    I've also stopped myself from calling classes instead of defs (I had
    the whole class in the __init__ def previously) and removed most of my
    global variables.

    Now I have twelve 1-6Kb files like login.py, plus an 18Kb main.py,
    instead of one 38Kb main.py to grep through!

    So it was worth the struggle to clean up a bit....
     
    simo, Apr 5, 2004
    #5
  6. > I had to resort to "from login import *" in main.py and then "import
    > wx" (and other modules like urllib/webbrowser etc) in login.py and it
    > all seems to work.


    Sounds ugly. I would stick with...

    #in main.py
    import login
    import wx

    #in login.py and others...
    import wx


    > I didn't occur to me that I'd have to import the modules used in each
    > module file, I thought it would work just from the parent (main.py)
    > file.


    You were misunderstanding modules, namespaces, etc.


    > I've also stopped myself from calling classes instead of defs (I had
    > the whole class in the __init__ def previously) and removed most of my
    > global variables.


    What do you mean "calling classes"? Show an example of what you were
    doing before, and what you are doing now, and I'm sure someone will tell
    you which is more "Pythonic" and/or which is a better design.


    > Now I have twelve 1-6Kb files like login.py, plus an 18Kb main.py,
    > instead of one 38Kb main.py to grep through!
    >
    > So it was worth the struggle to clean up a bit....


    Congrats.

    - Josiah
     
    Josiah Carlson, Apr 6, 2004
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.

Share This Page