473,657 Members | 2,953 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Scope and program structure problems

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

So it seems that if I want to write to the frame's statusbar, I can't
do anything re serial import until the frame is initialising. And I
can't put any serial import code after the app.Mainloop() code line
because it won't run until the frame closes.

In other words, I seem to be stuck with importing the serial library
either in the __init__ function or - if implemented slightly
differently - in a separate function of the wxPython Frame class, ie a
code structure of:

-----------
# 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

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

Apologies for the long post and hope that my description is clear
enough to make sense.

JGD
Jul 1 '08 #1
3 2473
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(se lf) # 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
misunderstandin g 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_e rror = None
except ImportError, e:
serial = None
serial_import_e rror = e
class Frame(wx.Frame) :
def __init__(self):
self.serial = None

def setup_serial(se lf):
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>
Jul 1 '08 #2
Many thanks for the repsonse - much appreciated.

And sorry - yes I was probably compounding two separate issues here -
the GUI one and the variable scope one. Maybe the wxPython list would
be the best place to ask more about the GUI side of things.

Then actually I can simplify my remaining question quite a lot - I
know you've partly answered this already but let me just rephrase
this:

It must be commonplace to first use a variable or object within one
function in a module and then want to use it again - perhaps still
with the same value as in the first function - in a second function.

So what's the recommended Python way round this? If I was using .Net
then I'd be declaring the variables/objects explicitly and could set
their scope according to how/where they were declared. But if the
Python way is not to declare vars before use then this must create
some problems for cross-function use.

So it is best to declare such vars at the module level (ie outside of
a function) and set eg to Null/None or to assign them with a keyword
such as global or static (assuming that concept applies in Python) at
first use inside a function or what?

JGD
Jul 1 '08 #3
John Dann a écrit :
Many thanks for the repsonse - much appreciated.

And sorry - yes I was probably compounding two separate issues here -
the GUI one and the variable scope one. Maybe the wxPython list would
be the best place to ask more about the GUI side of things.

Then actually I can simplify my remaining question quite a lot - I
know you've partly answered this already but let me just rephrase
this:

It must be commonplace to first use a variable or object
What difference do you make between a variable and an object in this
context ?
within one
function in a module and then want to use it again - perhaps still
with the same value
For which definition of "same value" ? Remember, Python has *no*
primitive types. Everything is an object.
as in the first function - in a second function.
So what's the recommended Python way round this?
This is way too general to give a single straight answer - whatever the
language FWIW. Are both function in the same module ? Are they methods
of a same object ? Is the first function calling the second or are they
totally unrelated ?
If I was using .Net
then I'd be declaring the variables/objects explicitly
I personnally find the assignment, import, class and def statements (all
having a binding behaviour) to be rather explicit.
and could set
their scope according to how/where they were declared.
Names bound at the top-level are globals to the module. Names bound
within a function (including arguments) are locals, unless there has
been a global statement for them before in the same function's body.
Names bound within a class statement lives in the class's namespace (IOW
: they become class attributes, shared by all instances). And names
bound as object attributes (using either obj.name = whatever or
setattr(obj, "name", whatever)) become, well, object attributes.

Now there may be a couple points worth paying attention to :

1/ some types (numerics, strings and tuples at least) are immutable.
When doing :

i = 1
i = 2

the second assignment doesnt mutate the integer object bound to i, but
rebinds i to another integer object.

2/ the scope of a name isn't necessarily related to the scope of the
object bound to that name.

As an example, function's parameters *names* are local to the function,
but the actual arguments - the objects passed when calling the function
- are not.

IOW, rebinding a parameter name withing a function body will rebind the
name locally, but will not affect the object originally bound to that
name. But *mutating* an object passed as argument *will* (off course)
affect the object outside the function.

But if the
Python way is not to declare vars before use
For which definition of "var" and "use" ? Did you really try to use a
name that didn't exist in the accessible namespace - I mean, "use" for
anything else than binding ?

The first binding of a name in a namespace *is* the 'declaration'. If a
name is not defined in the currently accessible namespace, and you try
to do anything else than binding it, you'll get an exception.
then this must create
some problems for cross-function use.
If what you mean is that it makes it harder to litter you code with true
global variables, then it's obviously a *very* good thing IMHO !-)

But no, there's no more problem with shared state in Python than in any
other (imperative) language I know - usually less in fact since there's
no "applicatio n global" namespace. Most of the time, the appropriate way
to share state is to use classes - heck, that's what they were created
for, isn't it ?-). Sharing state thru module-level variables is ok as
long you only access it for reading (pseudo-constants etc).

Sometimes, it's ok to use a module-level variable read-write, but this
should be restricted to this particular module's implementation stuff
(IOW : the name is not part of the API, and only functions / methods in
this same module access it), and never done without a clear enough
understanding of Python's namespaces and bindings.

So it is best to declare such vars at the module level (ie outside of
a function) and set eg to Null/None or to assign them with a keyword
such as global or static (assuming that concept applies in Python)
it doesnt.
at first use inside a function or what?
Usually, when you really need a module-level variable to be shared
read-write between functions, it happens that you can bind it to a
sensible default. Now what is a "sensible default" depends on the
concrete use case. Anyway, by all means, explicitely bind this name at
the top-level, before any code accessing it, and if possible with a
comment about this name being shared read/write by functions x and y.

My 2 cents...

Jul 1 '08 #4

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

7
5722
by: alphatan | last post by:
Is there relative source or document for this purpose? I've searched the index of "Mastering Regular Expression", but cannot get the useful information for C. Thanks in advanced. -- Learning is to improve, but not to prove.
5
2085
by: pembed2003 | last post by:
Hi all, I am reading the book "C How to Program" and in the chapter where it discuss scope rule, it says there are four scopes for a variable: function scope file scope block scope function-prototype scope I think(might be wrong):
3
3426
by: marco_segurini | last post by:
Hi, I am using VS 2005. If I compile the following code only line 6 returns me an error while line 9 returns a warning. If I comment the line 6 and debug the program the assignments of lines {9, 11} work fine. Why the '.' "scope operator" is accepted in line 9 and not in line 6?
7
1444
by: moondaddy | last post by:
I want to create a public enum that can be used throughout a project. I created an enum like this in a module: Public Enum ParentType Project = 0 Stage = 1 VIP = 2 Func = 3 Equipment = 4 Idea = 5
165
6827
by: Dieter | last post by:
Hi. In the snippet of code below, I'm trying to understand why when the struct dirent ** namelist is declared with "file" scope, I don't have a problem freeing the allocated memory. But when the struct is declared in main (block scope) it will segfault when passing namelist to freeFileNames().
5
1519
by: rick | last post by:
I'm working on a disassembler for a school project. Things work but I get compiler warnings as follows: cc -W -Wall -pedantic -ansi main.c defs.h:44: warning: 'blah' defined but not used blah is a static variable, so visible only to defs.h (and files that include defs.h?). Without the static qualifier the compiler bails with main.o: multiple definition of 'blah'
4
2570
by: AndrewD | last post by:
Hey C++ folks, I created this today, just for fun. You can make object allocation for any class around 6 times faster, simply by doing the following. class MyClass : public TXpQAlloc<MyClass,N> N is a chunking factor (defaults to 10).
2
4695
by: Laurent Deniau | last post by:
I would like to know why the following small program does not compile (checked with gcc 4.1.2) and if the compiler behavior is correct: struct A; typedef void (T)(struct A*); void f(void) { struct A { int _; } a; ((T*)0)(&a);
1
3755
by: Giacomo Catenazzi | last post by:
Hello, To learn the details of C, I've build the following example, could you check if it is correct and if it miss some important cases? Are there some useful (real cases) examples of: - "function prototype scope" for structures and unions? - "extern" for internal linkage ?
0
8820
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
8718
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
0
7314
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
1
6162
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5630
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
4150
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
4300
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
2726
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
2
1601
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.