Both Robin and Chris wrote in response to one of my questions that
supporting functions should be in modules separate from the main
application. I'm trying to do this, but run into a problem with the scope of
a variable. Let me try to briefly explain.
A.py contains the class MainFrame() and the entire wxPython UI. The
File->New and File->Open menus call the bound functions, OnFileNew() and
OnFileOpen() in the MainFrame class. These set the filename variable,
'projname,' that is the name of the project's SQLite3 database to be opened
or created. In other words, a.py is the master module that imports all the
other modules.
One of these other modules is b.py. It holds a single class with the
SQLite3 functions to open, create, and close the database connection. These
functions need the 'projname' variable, but b.py is not within the scope of
projname.
My understanding of variable scope is that projname is local to
OnFileOpen() and OnFileNew(), global within the class MainFrame(), and
enclosing within the a.py module. But, since it's not a built in variable
it's not visible to b.py. Of course, I cannot import a.py into b.py because
that sets up a circular reference.
What is the appropriate way to handle this situation? I moved the database
functions back into the MainFrame() class, but then had difficulties
getting a pysqlite2 cursor from another module.
Rich
···
--
Richard B. Shepard, Ph.D. | The Environmental Permitting
Applied Ecosystem Services, Inc.(TM) | Accelerator
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863
Both Robin and Chris wrote in response to one of my questions that
supporting functions should be in modules separate from the main
application. I'm trying to do this, but run into a problem with the scope of
a variable. Let me try to briefly explain.
A.py contains the class MainFrame() and the entire wxPython UI. The
File->New and File->Open menus call the bound functions, OnFileNew() and
OnFileOpen() in the MainFrame class. These set the filename variable,
'projname,' that is the name of the project's SQLite3 database to be opened
or created. In other words, a.py is the master module that imports all the
other modules.
One of these other modules is b.py. It holds a single class with the
SQLite3 functions to open, create, and close the database connection. These
functions need the 'projname' variable, but b.py is not within the scope of
projname.
You could pass 'projname' to b.py as a parameter when you instantiate the class (assuming that can happen after the UI has determined what the projname will be), and assign that value in your b.py class _init_ to something like 'self.projname'. This would make it available to everything within that instance of b.py during subsequent calls.
In my opinion, the more variables you pass by parameter and access by functional returns, the more reliable your modules and functions will be, and the less you will have to keep straight in your head while programming. Others may disagree.
···
My understanding of variable scope is that projname is local to
OnFileOpen() and OnFileNew(), global within the class MainFrame(), and
enclosing within the a.py module. But, since it's not a built in variable
it's not visible to b.py. Of course, I cannot import a.py into b.py because
that sets up a circular reference.
What is the appropriate way to handle this situation? I moved the database
functions back into the MainFrame() class, but then had difficulties
getting a pysqlite2 cursor from another module.
Rich
--
Dan Cherry
dscherry (@) bellsouth.net
Finding a solution to a problem doesn't solve the problem...
Implementing the solution solves the problem.
Interestingly enough, I stumbled into the middle of a thread on the python
mail list that addressed this exact issue. I created a new module,
config.py, that contains only "projname = ' '." By importing config in all
files needing that variable, it's made available to them.
This is, apparently, the same approach used by the 'singleton pattern' but
I've no idea what that is or when it's appropriate.
Now to fix the next bad reference across modules ...
Rich
···
On Fri, 3 Nov 2006, Dan Cherry wrote:
You could pass 'projname' to b.py as a parameter when you instantiate the
class (assuming that can happen after the UI has determined what the
projname will be), and assign that value in your b.py class _init_ to
something like 'self.projname'. This would make it available to
everything within that instance of b.py during subsequent calls.
In my opinion, the more variables you pass by parameter and access by
functional returns, the more reliable your modules and functions will be,
and the less you will have to keep straight in your head while
programming. Others may disagree.
--
Richard B. Shepard, Ph.D. | The Environmental Permitting
Applied Ecosystem Services, Inc.(TM) | Accelerator
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863
Interestingly enough, I stumbled into the middle of a thread on the python
mail list that addressed this exact issue. I created a new module,
config.py, that contains only "projname = ' '." By importing config in all
files needing that variable, it's made available to them.
This is, apparently, the same approach used by the 'singleton pattern'
yup. You could google it, but essentially, the 'singleton pattern' is simply when you have a class that there is designed to be only a single instance of.
In Python, everything is about namespaces. A class, a class instance, a module -- they are all simply different namespaces, with slightly different rules about how names are resolved.
I use a Config.py module quite frequently in my code. However, I usually put a few classes in it to hold different types of information, rather than putting it all in the global namespace. That also makes it easier to have methods (or properties) to set values. If you put them all in the module global namespace , you have to make the attributes global to set them.
-Chris
···
--
Christopher Barker, Ph.D.
Oceanographer
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception
I use a Config.py module quite frequently in my code. However, I usually
put a few classes in it to hold different types of information, rather
than putting it all in the global namespace. That also makes it easier to
have methods (or properties) to set values. If you put them all in the
module global namespace , you have to make the attributes global to set
them.
--
Richard B. Shepard, Ph.D. | The Environmental Permitting
Applied Ecosystem Services, Inc.(TM) | Accelerator
<http://www.appl-ecosys.com> Voice: 503-667-4517 Fax: 503-667-8863