Re: How to initialize a class variable once

2008-12-09 Thread Roy Smith
In article <[EMAIL PROTECTED]>,
 Joe Strout <[EMAIL PROTECTED]> wrote:

> On Dec 9, 2008, at 4:31 AM, Brian Allen Vanderburg II wrote:
> 
> > There is one situation where a module can be imported/executed  
> > twice, if it is the __main__ module.

> Anyway, thanks for pointing this out; I bet it's the root cause of the  
> OP's observation.

Wow, good diagnosis!  This was happening in a test framework (using 
unittest).  I had a class which had a @staticmethod factory function, and a 
class member dict where __init__() registered every instance of the class 
that got created.  

Something was going wrong, so in my test code (i.e. in __main__), I 
imported the module directly and printed the dict.  Lo and behold, it was 
empty!  As far as I could tell,

class Foo:
   _map = {}

was getting executed again, which made no sense.  I even went as far as 
printing out id(Foo) in both places to make sure I really had the same 
class (I did).

Thanks for the help.  I never would have figured this out on my own.
--
http://mail.python.org/mailman/listinfo/python-list


Re: How to initialize a class variable once

2008-12-09 Thread George Sakkis
On Dec 9, 10:36 am, Joe Strout <[EMAIL PROTECTED]> wrote:

> On Dec 9, 2008, at 4:31 AM, Brian Allen Vanderburg II wrote:
>
> > There is one situation where a module can be imported/executed  
> > twice, if it is the __main__ module.
>
> That's an excellent point -- this is something I've run into, and it  
> always feels a bit awkward to code around it. What's the standard  
> idiom for avoiding this issue in a complex app?  Have a "main" file  
> that is not imported by anything else, and which does little but  
> launch stuff from some other module?

Yes, I believe that's the common practice. Still, whenever I end up
putting stuff in a "main" file and run into the double import problem
(e.g. when pickling), I do an explicit "from main import *" after all
the definitions, i.e.:

# myscript.py

__all__ = ['foo', 'Bar']

def foo(x,y):
   ...

class Bar(object):
   

from myscript import *

if __name__ == '__main__':
assert foo.__module__ == Bar.__module__ == 'myscript'


George
--
http://mail.python.org/mailman/listinfo/python-list


Re: How to initialize a class variable once

2008-12-09 Thread Joe Strout

On Dec 9, 2008, at 4:31 AM, Brian Allen Vanderburg II wrote:

There is one situation where a module can be imported/executed  
twice, if it is the __main__ module.


That's an excellent point -- this is something I've run into, and it  
always feels a bit awkward to code around it. What's the standard  
idiom for avoiding this issue in a complex app?  Have a "main" file  
that is not imported by anything else, and which does little but  
launch stuff from some other module?


As I say it, that seems obvious, but somehow I keep getting urges to  
put global stuff (like my Application subclass) in the main file, and  
then I find I need to reference it from some other module, and get  
into trouble.  This is probably just bias from my last programming  
environment, though.  I can adapt.


Anyway, thanks for pointing this out; I bet it's the root cause of the  
OP's observation.


Best,
- Joe

--
http://mail.python.org/mailman/listinfo/python-list


Re: How to initialize a class variable once

2008-12-09 Thread Brian Allen Vanderburg II

[EMAIL PROTECTED] wrote:


Unless you are calling reload() on the module, it will only ever get
_loaded_ once. Each additional import will just yield the existing
module. Perhaps if you post an example of the behavior that leads you
to believe that the class variables are getting reinitialized I can
provide more useful help.

Matt
--
http://mail.python.org/mailman/listinfo/python-list
  


There is one situation where a module can be imported/executed twice, if 
it is the __main__ module.  Obviously the example below would be 
considered bad Python practice but it just shows how it can be done:


main.py:

class Blah(object):
   def action(self):
   print "action"

print "import"

if __name__ == "__main__":
   import app
   app.run()


app.py:

def run():
   import main
   blah = main.Blah()
   blah.action()


python main.py:

import
import
action

The reason is the first time main.py gets loaded, it is known as 
'__main__' but when app imports main, it is not in sys.modules so it 
loads 'main.py' again but this time as 'main'


Brian Vanderburg II


--
http://mail.python.org/mailman/listinfo/python-list


Re: How to initialize a class variable once

2008-12-08 Thread Roy Smith
In article 
<[EMAIL PROTECTED]>,
 alex23 <[EMAIL PROTECTED]> wrote:

> You might need to provide some more details about your code.

It's going to take me some time to generate a minimal test case.
--
http://mail.python.org/mailman/listinfo/python-list


Re: How to initialize a class variable once

2008-12-08 Thread Benjamin Kaplan
On Mon, Dec 8, 2008 at 11:44 PM, John Machin <[EMAIL PROTECTED]> wrote:

> On Dec 9, 3:36 pm, Matimus <[EMAIL PROTECTED]> wrote:
> > On Dec 8, 8:08 pm, Roy Smith <[EMAIL PROTECTED]> wrote:
> >
> > > I've got a class with a class variable:
> >
> > > class Foo:
> > >_map = {}
> >
> > > How do I make sure this only gets initialized the *first* time the
> > > module containing the class is imported?  What appears to be happening
> > > as it stands is each time the module gets imported, Foo._map get re-
> > > initialized.
> >
> > Unless you are calling reload() on the module, it will only ever get
> > _loaded_ once. Each additional import will just yield the existing
> > module. Perhaps if you post an example of the behavior that leads you
> > to believe that the class variables are getting reinitialized
>
> and change it to
>   class Foo(object):
> because we care little about old-style classes these days


unless the OP is using Python 3 in which case that would be redundant. This
is going to be really confusing unless every poster lists their python
version.



>
> and put a print statement in the module just before the class
> statement and print statements before and after each import statement
> so that we can see what is happening.
> --
> http://mail.python.org/mailman/listinfo/python-list
>
--
http://mail.python.org/mailman/listinfo/python-list


Re: How to initialize a class variable once

2008-12-08 Thread John Machin
On Dec 9, 3:36 pm, Matimus <[EMAIL PROTECTED]> wrote:
> On Dec 8, 8:08 pm, Roy Smith <[EMAIL PROTECTED]> wrote:
>
> > I've got a class with a class variable:
>
> > class Foo:
> >    _map = {}
>
> > How do I make sure this only gets initialized the *first* time the
> > module containing the class is imported?  What appears to be happening
> > as it stands is each time the module gets imported, Foo._map get re-
> > initialized.
>
> Unless you are calling reload() on the module, it will only ever get
> _loaded_ once. Each additional import will just yield the existing
> module. Perhaps if you post an example of the behavior that leads you
> to believe that the class variables are getting reinitialized

and change it to
   class Foo(object):
because we care little about old-style classes these days
and put a print statement in the module just before the class
statement and print statements before and after each import statement
so that we can see what is happening.
--
http://mail.python.org/mailman/listinfo/python-list


Re: How to initialize a class variable once

2008-12-08 Thread alex23
On Dec 9, 2:08 pm, Roy Smith <[EMAIL PROTECTED]> wrote:
> I've got a class with a class variable:
>
> class Foo:
>    _map = {}
>
> How do I make sure this only gets initialized the *first* time the
> module containing the class is imported?  What appears to be happening
> as it stands is each time the module gets imported, Foo._map get re-
> initialized.

What you're asking for is actually the default behaviour. The Foo
class should only be created once, on the first import, and all
subsequent imports should refer to it:

foo.py:
class Foo:
_map = {}

a.py:
from foo import Foo
Foo._map['a'] = 1

b.py:
from foo import Foo
print Foo._map

c.py:
import a
import b

This outputs "{'a': 1}", as expected. The Foo._map that b.py prints is
the same Foo._map that a.py has modified.

You might need to provide some more details about your code.
--
http://mail.python.org/mailman/listinfo/python-list


Re: How to initialize a class variable once

2008-12-08 Thread Matimus
On Dec 8, 8:08 pm, Roy Smith <[EMAIL PROTECTED]> wrote:
> I've got a class with a class variable:
>
> class Foo:
>    _map = {}
>
> How do I make sure this only gets initialized the *first* time the
> module containing the class is imported?  What appears to be happening
> as it stands is each time the module gets imported, Foo._map get re-
> initialized.

Unless you are calling reload() on the module, it will only ever get
_loaded_ once. Each additional import will just yield the existing
module. Perhaps if you post an example of the behavior that leads you
to believe that the class variables are getting reinitialized I can
provide more useful help.

Matt
--
http://mail.python.org/mailman/listinfo/python-list