Scope and program structure problems

Bruno Desthuilliers bruno.42.desthuilliers at websiteburo.invalid
Tue Jul 1 14:20:37 CEST 2008


John Dann a écrit :
> Trying to learn Python here, but getting tangled up with variable
> scope across functions, modules etc and associated problems. Can
> anyone advise please?
> 
> Learning project is a GUI-based (wxPython) Python program that needs
> to access external data across a serial port. 
> 
> The first thing that I need the program to do when it starts up is to
> check that it can see the serial port, the first step of which is to
> check that it can import the pySerial module, and display an
> appropriate message in the statusbar of the main frame. (I know there
> may be other ways of doing this but this is what I'm trying to do
> currently and I'd like to understand how to make this approach work
> robustly even if there are other options.)
> 
(snip)
> 
> -----------
> # Can't put serial import code here because there's no GUI yet to send
> messages to.
> 
> Class Frame(wx.Frame)
>     def __init__()
>         etc
>     #code to check and use serial port has to go below??
>     def CheckSerial() # eg triggered by appropriate menu click event
>         Try:
>             import serial
>         etc
>         ser = Serial.etc  # set ser object as handle to serial port
>     def UseSerial():
>         # Code to perform serial IO
> 
> app=App(wx.App)
> app.MainLoop()
> 
> # Can't put serial import code here because it won't execute until
> frame closes?
> -----------
> 
> But then I hit another problem. If I set the object ser to point to
> the serial port in the CheckSerial function, then it's just got local
> scope within the function and can't be seen from the UseSerial
> function.
> 
> So I've got 2 questions. The main one is whether there's any way of
> explicitly giving the ser object global scope in the code line:
> 
>         ser = Serial.etc  # set ser object as handle to serial port

It is possible - for the python definition of 'global' being 
'module-global' - but it's not necessarily the best solution. Look up 
the doc for the 'global' statement to learn more.

Another solution would be to make ser an attribute of your Frame object:

class Frame(wx.Frame):
     def __init__(self):
         self.serial = None

     #code to check and use serial port has to go below??
     def setup_serial(self) # eg triggered by appropriate menu click event
         try:
             import serial
         except ImportError, e:
             # display an error message and either crash
             # or return

         else:
              # set self.serial object as handle to serial port
              self.serial = serial.etc()


     def use_serial(self):
         # Code to perform serial IO
         # won't work if setupSerial failed

> And, second, does my overall description above reveal any serious
> misunderstanding about how best to handle this sort of problem in
> Python?

Well... You'd get a very similar result by doing your import at the 
top-level but within a try/except block, then when you have a gui setup 
takes appropriate actions.

try:
     import serial
     serial_import_error = None
except ImportError, e:
     serial = None
     serial_import_error = e


class Frame(wx.Frame):
     def __init__(self):
         self.serial = None

     def setup_serial(self):
         if serial is None:
             # display an error message and either crash
             # or return
         else:
             self.serial = serial.whatever()



<disclaimer>

But anyway: I have no real (read : anything requiring any brain-cell) 
experience writing rich GUI apps in Python, and I haven't done rich GUI 
programming for four last years at least, so there may be better 
solutions here.

So : Any wxPython guru around ?-)

</disclaimer>



More information about the Python-list mailing list