Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]
Groups > comp.lang.python > #38253 > unrolled thread
| Started by | CM <cmpython@gmail.com> |
|---|---|
| First post | 2013-02-05 20:40 -0800 |
| Last post | 2013-02-06 18:08 -0700 |
| Articles | 14 — 6 participants |
Back to article view | Back to comp.lang.python
best way to share an instance of a class among modules? CM <cmpython@gmail.com> - 2013-02-05 20:40 -0800
Re: best way to share an instance of a class among modules? Terry Reedy <tjreedy@udel.edu> - 2013-02-06 00:04 -0500
Re: best way to share an instance of a class among modules? CM <cmpython@gmail.com> - 2013-02-06 14:41 -0800
Re: best way to share an instance of a class among modules? Michael Torrie <torriem@gmail.com> - 2013-02-06 17:03 -0700
Re: best way to share an instance of a class among modules? c <chaelon@gmail.com> - 2013-02-06 16:43 -0800
Re: best way to share an instance of a class among modules? Ethan Furman <ethan@stoneleaf.us> - 2013-02-06 16:57 -0800
Re: best way to share an instance of a class among modules? Ethan Furman <ethan@stoneleaf.us> - 2013-02-06 17:36 -0800
Re: best way to share an instance of a class among modules? Rick Johnson <rantingrickjohnson@gmail.com> - 2013-02-07 18:14 -0800
Re: best way to share an instance of a class among modules? Michael Torrie <torriem@gmail.com> - 2013-02-07 23:05 -0700
Re: best way to share an instance of a class among modules? Michael Torrie <torriem@gmail.com> - 2013-02-08 21:54 -0700
Re: best way to share an instance of a class among modules? Rick Johnson <rantingrickjohnson@gmail.com> - 2013-02-07 18:14 -0800
Re: best way to share an instance of a class among modules? Michael Torrie <torriem@gmail.com> - 2013-02-06 17:14 -0700
Re: best way to share an instance of a class among modules? CM <cmpython@gmail.com> - 2013-02-06 16:45 -0800
Re: best way to share an instance of a class among modules? Michael Torrie <torriem@gmail.com> - 2013-02-06 18:08 -0700
| From | CM <cmpython@gmail.com> |
|---|---|
| Date | 2013-02-05 20:40 -0800 |
| Subject | best way to share an instance of a class among modules? |
| Message-ID | <15fe7153-a77a-49eb-9cf8-d4e59b4a2079@z9g2000vbx.googlegroups.com> |
I have recently moved all my SQLite3 database-related functions into a class, DatabaseAccess, that lives in a "utilities" module. When the application loads, the namespace of the instance of the class is populated with two different cursors for two different databases the whole application needs to use. One of those cursors always refers to a connection to the same database, but the other cursor can change which database it refers to; in this regard, the namespace of the DatabaseAccess class instance holds a "state" (which is which database the one cursor currently refers to) I have a number of modules that all need to use those two cursors. However, if I import the utilities module and create a new instance of the DatabasesAccess() in each of all the various modules, obviously each new instance doesn't have the same namespace as the first instance, and so doesn't have the *same* two cursors. I can think of a few ways to pass the DatabaseAcess instance around to the various modules, but all of them seem like repeating myself and clunky. What's the "best" (most Pythonic, simplest) way for a number of modules to all share the same instance of my DatabaseAccess class? Thanks, Che
[toc] | [next] | [standalone]
| From | Terry Reedy <tjreedy@udel.edu> |
|---|---|
| Date | 2013-02-06 00:04 -0500 |
| Message-ID | <mailman.1401.1360127082.2939.python-list@python.org> |
| In reply to | #38253 |
On 2/5/2013 11:40 PM, CM wrote: > I have recently moved all my SQLite3 database-related functions into a > class, DatabaseAccess, that lives in a "utilities" module. When the > application loads, the namespace of the instance of the class is > populated with two different cursors for two different databases the > whole application needs to use. One of those cursors always refers to > a connection to the same database, but the other cursor can change > which database it refers to; in this regard, the namespace of the > DatabaseAccess class instance holds a "state" (which is which database > the one cursor currently refers to) > > I have a number of modules that all need to use those two cursors. > However, if I import the utilities module and create a new instance of > the DatabasesAccess() in each of all the various modules, obviously > each new instance doesn't have the same namespace as the first > instance, and so doesn't have the *same* two cursors. > > I can think of a few ways to pass the DatabaseAcess instance around to > the various modules, but all of them seem like repeating myself and > clunky. What's the "best" (most Pythonic, simplest) way for a number > of modules to all share the same instance of my DatabaseAccess class? Attach the instance of the class to the utilities module that clients import. It does not matter if the code is in the utilities module itself or in one of the importing modules (possibly the first). # in module shared_cursor = # in importer import utilities utilities.shared_cursor = DatabaseAccess(args) Module attributes are mutable and can be set from elsewhere. -- Terry Jan Reedy
[toc] | [prev] | [next] | [standalone]
| From | CM <cmpython@gmail.com> |
|---|---|
| Date | 2013-02-06 14:41 -0800 |
| Message-ID | <5db4add7-ab9c-4311-b3b6-24156cd6f248@z4g2000vbz.googlegroups.com> |
| In reply to | #38254 |
On Feb 6, 12:04 am, Terry Reedy <tjre...@udel.edu> wrote:
> On 2/5/2013 11:40 PM, CM wrote:
>
>
>
>
>
>
>
>
>
> > I have recently moved all my SQLite3 database-related functions into a
> > class, DatabaseAccess, that lives in a "utilities" module. When the
> > application loads, the namespace of the instance of the class is
> > populated with two different cursors for two different databases the
> > whole application needs to use. One of those cursors always refers to
> > a connection to the same database, but the other cursor can change
> > which database it refers to; in this regard, the namespace of the
> > DatabaseAccess class instance holds a "state" (which is which database
> > the one cursor currently refers to)
>
> > I have a number of modules that all need to use those two cursors.
> > However, if I import the utilities module and create a new instance of
> > the DatabasesAccess() in each of all the various modules, obviously
> > each new instance doesn't have the same namespace as the first
> > instance, and so doesn't have the *same* two cursors.
>
> > I can think of a few ways to pass the DatabaseAcess instance around to
> > the various modules, but all of them seem like repeating myself and
> > clunky. What's the "best" (most Pythonic, simplest) way for a number
> > of modules to all share the same instance of my DatabaseAccess class?
>
> Attach the instance of the class to the utilities module that clients
> import. It does not matter if the code is in the utilities module itself
> or in one of the importing modules (possibly the first).
>
> # in module
> shared_cursor =
>
> # in importer
> import utilities
> utilities.shared_cursor = DatabaseAccess(args)
>
> Module attributes are mutable and can be set from elsewhere.
>
> --
> Terry Jan Reedy
Thank you. But, I'm sorry, I'm not following this enough to get it to
work. Shouldn't it be a little more like this:
# in utilities module
shared_cursor = DatabaseAccess_instance #but how? see my question
below...
# in importer
import utilities
self.shared_cursor = utilities.shared_cursor ("self" is here to make
cursor available to all functions in importer
My only problem, then, is I create the shared_cursor from within a
function within the instance of DatabaseAccess(). How then do I pass
it from within the function's namespace to the module's namespace so
that I can do that first line?
[toc] | [prev] | [next] | [standalone]
| From | Michael Torrie <torriem@gmail.com> |
|---|---|
| Date | 2013-02-06 17:03 -0700 |
| Message-ID | <mailman.1432.1360195406.2939.python-list@python.org> |
| In reply to | #38310 |
On 02/06/2013 03:41 PM, CM wrote:
> Thank you. But, I'm sorry, I'm not following this enough to get it to
> work. Shouldn't it be a little more like this:
No, not exactly.
>
> # in utilities module
> shared_cursor = DatabaseAccess_instance #but how? see my question
> below...
How what?
> # in importer
> import utilities
> self.shared_cursor = utilities.shared_cursor ("self" is here to make
> cursor available to all functions in importer
Umm no. For one you're using self incorrectly. For two, it already is
visible to all functions in the module. You just have to refer to it as
"utilities.shared_cursor."
> My only problem, then, is I create the shared_cursor from within a
> function within the instance of DatabaseAccess(). How then do I pass
> it from within the function's namespace to the module's namespace so
> that I can do that first line?
Every function in a module has access to the module's global namespace.
And your shared_cursor is there, inside of the utilities reference,
since utilities was imported into your module, "importer."
[toc] | [prev] | [next] | [standalone]
| From | c <chaelon@gmail.com> |
|---|---|
| Date | 2013-02-06 16:43 -0800 |
| Message-ID | <aa4c4a88-5d14-4875-aa1c-0e611cc0badd@z4g2000vbz.googlegroups.com> |
| In reply to | #38318 |
On Feb 6, 7:03 pm, Michael Torrie <torr...@gmail.com> wrote:
> On 02/06/2013 03:41 PM, CM wrote:
>
> > Thank you. But, I'm sorry, I'm not following this enough to get it to
> > work. Shouldn't it be a little more like this:
>
> No, not exactly.
>
>
>
> > # in utilities module
> > shared_cursor = DatabaseAccess_instance #but how? see my question
> > below...
>
> How what?
>
> > # in importer
> > import utilities
> > self.shared_cursor = utilities.shared_cursor ("self" is here to make
> > cursor available to all functions in importer
>
> Umm no. For one you're using self incorrectly. For two, it already is
> visible to all functions in the module. You just have to refer to it as
> "utilities.shared_cursor."
I was using self correctly, I think; but I should have said that the
code in the importing module would be within a class, so self there
refers to that class. But that's a side point.
I agree that utilities.shared_cursor is visible within the importing
module. But the problem below remains for me...
> > My only problem, then, is I create the shared_cursor from within a
> > function within the instance of DatabaseAccess(). How then do I pass
> > it from within the function's namespace to the module's namespace so
> > that I can do that first line?
>
> Every function in a module has access to the module's global namespace.
> And your shared_cursor is there, inside of the utilities reference,
> since utilities was imported into your module, "importer."
But the function in the module is also within a *class* so I don't
think the function does have access to the module's global namespace.
Here's the hierarchy:
-- Module namespace....
---- class namespace (DatabaseAccess is the name of the class)
---- function namespace
This is where the cursor is created. How do I get it
into the module namespace?
Che
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2013-02-06 16:57 -0800 |
| Message-ID | <mailman.1435.1360199783.2939.python-list@python.org> |
| In reply to | #38320 |
On 02/06/2013 04:43 PM, c wrote:
> But the function in the module is also within a *class* so I don't
> think the function does have access to the module's global namespace.
> Here's the hierarchy:
>
> -- Module namespace....
> ---- class namespace (DatabaseAccess is the name of the class)
> ---- function namespace
> This is where the cursor is created. How do I get it
> into the module namespace?
In the class namespace you have something like:
self.shared_cursor = ...
to get that into the module namespace instead, just remove the 'self':
shared_cursor = ...
--
~Ethan~
[toc] | [prev] | [next] | [standalone]
| From | Ethan Furman <ethan@stoneleaf.us> |
|---|---|
| Date | 2013-02-06 17:36 -0800 |
| Message-ID | <mailman.1436.1360202172.2939.python-list@python.org> |
| In reply to | #38320 |
On 02/06/2013 04:57 PM, Ethan Furman wrote:
> On 02/06/2013 04:43 PM, c wrote:
>> But the function in the module is also within a *class* so I don't
>> think the function does have access to the module's global namespace.
>> Here's the hierarchy:
>>
>> -- Module namespace....
>> ---- class namespace (DatabaseAccess is the name of the class)
>> ---- function namespace
>> This is where the cursor is created. How do I get it
>> into the module namespace?
>
> In the class namespace you have something like:
>
> self.shared_cursor = ...
>
> to get that into the module namespace instead, just remove the 'self':
>
> shared_cursor = ...
Correction:
As Michael Torrie pointed out, the 'global' keyword is needed:
global shared_cursor
shared_cursor = ...
[toc] | [prev] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2013-02-07 18:14 -0800 |
| Message-ID | <5b81481d-b7ee-40a2-92ba-4bfb174e1694@googlegroups.com> |
| In reply to | #38324 |
On Wednesday, February 6, 2013 7:36:28 PM UTC-6, Ethan Furman wrote: > As Michael Torrie pointed out, the 'global' keyword is needed: Wrong. The global keyword is in fact NOT needed and something i consider to be another wart of the language (PyWart on this subject coming soon!). Now, whilst Micheal's advice is valid python code, i would strongly suggest against encouraging people to use the global keyword when they could simply declare the variable beforehand. I know what you are thinking: """ But python does not /require/ us to declare global variables if we use the global keyword""" Yes, i know. But i just hate to have variables created "magically" in the middle of execution! ESPECIALLY if these variables are going to be accessed from another module(s). *sniff-sniff* does anyone smell what i smell? Listen. I want to know every variable and every CONSTANT that will exist in the module namespace, and i want to know these facts BEFORE i read anything else. So please declare them at the top of each module. Hierarchy of module code structure: 0. shebang lines 1. stdlib import statements 2. 3rd party and dependency import statements 3. CONSTANTS 4. $globalVariables 5. module functions 6. module classes (bka: Object Definitions) 7. Testing Area So if you want to use "global variables" , (bka: Module level variables), then simply declare them with a None value like this: globalVariable = None But don't pat yourself on the back just yet! Place a little comment so the reader will understand that this variable is accessed from ANOTHER namespace. sharedCursor = None # Set by "Class.blah"; Whored out to X,Y and Z! In this manner i will not be blindsided by proper use of poor language features.
[toc] | [prev] | [next] | [standalone]
| From | Michael Torrie <torriem@gmail.com> |
|---|---|
| Date | 2013-02-07 23:05 -0700 |
| Message-ID | <mailman.1479.1360303575.2939.python-list@python.org> |
| In reply to | #38395 |
On 02/07/2013 07:14 PM, Rick Johnson wrote:
> On Wednesday, February 6, 2013 7:36:28 PM UTC-6, Ethan Furman wrote:
>> As Michael Torrie pointed out, the 'global' keyword is needed:
>
> Wrong. The global keyword is in fact NOT needed and something i
> consider to be another wart of the language (PyWart on this subject
> coming soon!).
Actually in both Python 2 and 3, the global keyword is, in fact needed.
Otherwise the name binding in the function hides the global name. So
no matter if you declare the variable in the module itself (which yes I
agree you should always do!), you need the global keyword in the
function if you want to overwrite the name in the module's global namespace.
Observe the following code which I tested on both python2 and python3:
--------
from __future__ import print_function
my_global_var = 4
def test_func():
#global my_global_var
my_global_var = 6
if __name__ == "__main__":
print(my_global_var)
test_func()
print(my_global_var)
---------
Without the global statement, you get 4 printed out both times. At
least on the python interpreters I have handy. With the global
statement uncommented, I get 4 and 6.
Do you understand the difference between binding a name to an object and
variable assignment? Because that's the reason we see this behavior.
This would be a gotcha in this case. Not a wart, but simply something
to be aware of.
[toc] | [prev] | [next] | [standalone]
| From | Michael Torrie <torriem@gmail.com> |
|---|---|
| Date | 2013-02-08 21:54 -0700 |
| Message-ID | <mailman.1532.1360385670.2939.python-list@python.org> |
| In reply to | #38395 |
On 02/07/2013 07:14 PM, Rick Johnson wrote: > So if you want to use "global variables" , (bka: Module level > variables), then simply declare them with a None value like this: > > globalVariable = None This is a nice convention, but at best it's just a helpful notation that helps a programmer know something useful may likely be bound to this name in the future. The '=' sign in Python isn't an assignment operator, at least in this case; it's a binding operator. Thus any future line that sets globalVariable to something isn't assigning a value to this already-declared variable. Instead it's binding the name globalValue to a new object, and overwriting the name in the module dictionary. That's of course why the global keyword is required, so that Python will use the module dictionary instead of the local scope one.
[toc] | [prev] | [next] | [standalone]
| From | Rick Johnson <rantingrickjohnson@gmail.com> |
|---|---|
| Date | 2013-02-07 18:14 -0800 |
| Message-ID | <mailman.1469.1360289657.2939.python-list@python.org> |
| In reply to | #38324 |
On Wednesday, February 6, 2013 7:36:28 PM UTC-6, Ethan Furman wrote: > As Michael Torrie pointed out, the 'global' keyword is needed: Wrong. The global keyword is in fact NOT needed and something i consider to be another wart of the language (PyWart on this subject coming soon!). Now, whilst Micheal's advice is valid python code, i would strongly suggest against encouraging people to use the global keyword when they could simply declare the variable beforehand. I know what you are thinking: """ But python does not /require/ us to declare global variables if we use the global keyword""" Yes, i know. But i just hate to have variables created "magically" in the middle of execution! ESPECIALLY if these variables are going to be accessed from another module(s). *sniff-sniff* does anyone smell what i smell? Listen. I want to know every variable and every CONSTANT that will exist in the module namespace, and i want to know these facts BEFORE i read anything else. So please declare them at the top of each module. Hierarchy of module code structure: 0. shebang lines 1. stdlib import statements 2. 3rd party and dependency import statements 3. CONSTANTS 4. $globalVariables 5. module functions 6. module classes (bka: Object Definitions) 7. Testing Area So if you want to use "global variables" , (bka: Module level variables), then simply declare them with a None value like this: globalVariable = None But don't pat yourself on the back just yet! Place a little comment so the reader will understand that this variable is accessed from ANOTHER namespace. sharedCursor = None # Set by "Class.blah"; Whored out to X,Y and Z! In this manner i will not be blindsided by proper use of poor language features.
[toc] | [prev] | [next] | [standalone]
| From | Michael Torrie <torriem@gmail.com> |
|---|---|
| Date | 2013-02-06 17:14 -0700 |
| Message-ID | <mailman.1433.1360196074.2939.python-list@python.org> |
| In reply to | #38310 |
On 02/06/2013 05:03 PM, Michael Torrie wrote:
> Every function in a module has access to the module's global namespace.
> And your shared_cursor is there, inside of the utilities reference,
> since utilities was imported into your module, "importer."
Just to be clear:
mod1.py:
a=5
------------------------
mod2.py:
import mod1
def testfunc1():
print mod1.a
def testfunc2():
mod1.a = 6
-------------------------
main.py:
import mod1
import mod2
mod2.testfunc1()
mod2.testfunc2()
mod2.testfunc1()
-----------------------
The main.py program will print out "5" and "6."
If I understand your original question, this example will demonstrate
it. But I could have understood wrong!
[toc] | [prev] | [next] | [standalone]
| From | CM <cmpython@gmail.com> |
|---|---|
| Date | 2013-02-06 16:45 -0800 |
| Message-ID | <ef7640df-034a-4c20-a58a-53117c6f4a56@cd3g2000vbb.googlegroups.com> |
| In reply to | #38319 |
I was using self correctly, I think; but I should have said that the
code in the importing module would be within a class, so self there
refers to that class. But that's a side point.
I agree that utilities.shared_cursor is visible within the importing
module. But the problem below remains for me...
> > My only problem, then, is I create the shared_cursor from within a
> > function within the instance of DatabaseAccess(). How then do I pass
> > it from within the function's namespace to the module's namespace so
> > that I can do that first line?
> Every function in a module has access to the module's global namespace.
> And your shared_cursor is there, inside of the utilities reference,
> since utilities was imported into your module, "importer."
But the function in the module is also within a *class* so I don't
think the function does have access to the module's global namespace.
Here's the hierarchy:
-- Module namespace....
---- class namespace (DatabaseAccess is the name of the class)
---- function namespace
This is where the cursor is created. How do I get it
into the module namespace?
[toc] | [prev] | [next] | [standalone]
| From | Michael Torrie <torriem@gmail.com> |
|---|---|
| Date | 2013-02-06 18:08 -0700 |
| Message-ID | <mailman.1434.1360199338.2939.python-list@python.org> |
| In reply to | #38321 |
On 02/06/2013 05:45 PM, CM wrote:
> But the function in the module is also within a *class* so I don't
> think the function does have access to the module's global namespace.
> Here's the hierarchy:
>
> -- Module namespace....
> ---- class namespace (DatabaseAccess is the name of the class)
> ---- function namespace
> This is where the cursor is created. How do I get it
> into the module namespace?
Oh I see. You're trying to set a variable in the current module's
global namespace. There's two ways to do this, the first one is cleaner
and preferred:
1. Have a function in DatabaseAccess return the cursor then then set it
to a name in code that runs at the module level.
2. use the "global" keyword in the method:
def mymethod(self):
global blah
blah = something
Then your module has has blah in it's global method now. If you want to
stick a variable in another method's global namespace, as long as you've
imported it you just go:
module.newvariable = something
[toc] | [prev] | [standalone]
Back to top | Article view | comp.lang.python
csiph-web