Module import problems

S

simo

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....
 
P

Peter Hansen

simo said:
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
 
S

simo

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
 
P

Peter Hansen

simo said:
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
 
S

simo

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....
 
J

Josiah Carlson

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
 

Ask a Question

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

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,756
Messages
2,569,535
Members
45,008
Latest member
obedient dusk

Latest Threads

Top