Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Python > Re: Singleton implementation problems

Reply
Thread Tools

Re: Singleton implementation problems

 
 
Peter Otten
Guest
Posts: n/a
 
      07-04-2008
Urizev wrote:

> Hi everyone
>
> I have developed the singleton implementation. However I have found a
> strange behaviour when using from different files. The code is
> attached.
>
> Executing main


> New singleton:
> <__main__.Singleton instance at 0x2b98be474a70>


> New singleton:
> <myset.Singleton instance at 0x2b98be474d88>


> I do not know why, but it creates two instances of the singleton. Does
> anybody know why?


Do you see it now I snipped the irrelevant output?

The problem is the structure of your program. The myset module is imported
twice by Python, once as "myset" and once as "__main__". Therefore you get
two distinct MySet classes, and consequently two distinct MySet.__instance
class attributes.

Move the

if __name__ == "__main__": ...

statements into a separate module, e. g. main.py:

import myset
import member

if __name__ == "__main__":
print "Executing main"
set1 = myset.MySet()
set2 = myset.MySet()

mbr1 = member.Member()
mbr2 = member.Member()
mbr3 = member.Member()

Now main.py and member.py share the same instance of the myset module and
should work as expected.

Peter

 
Reply With Quote
 
 
 
 
Matthew Fitzgibbons
Guest
Posts: n/a
 
      07-04-2008
Ben Finney wrote:
> Peter Otten <(E-Mail Removed)> writes:
>
>> The problem is the structure of your program. The myset module is
>> imported twice by Python, once as "myset" and once as "__main__".

>
> Yes, this is the problem. Each module imports the other.
>
>> Therefore you get two distinct MySet classes, and consequently two
>> distinct MySet.__instance class attributes.

>
> Are you sure? This goes against my understanding: that 'import foo'
> will not re-import a module that's already been imported, but will
> instead simply return the existing module.
>
> So, I think if one evaluated 'myset is __main__', you'd find they are
> exactly the same module under different names; and therefore that
> there is only *one* instance of 'MySet', again under two names.
>


You can see that they're distinct by checking the addresses (the
instances in the OP also have different addresses). Besides, __main__
isn't imported normally.

-Matt

 
Reply With Quote
 
 
 
 
Peter Otten
Guest
Posts: n/a
 
      07-04-2008
Ben Finney wrote:

> Peter Otten <(E-Mail Removed)> writes:
>
>> The problem is the structure of your program. The myset module is
>> imported twice by Python, once as "myset" and once as "__main__".

>
> Yes, this is the problem. Each module imports the other.
>
>> Therefore you get two distinct MySet classes, and consequently two
>> distinct MySet.__instance class attributes.

>
> Are you sure? This goes against my understanding: that 'import foo'
> will not re-import a module that's already been imported, but will
> instead simply return the existing module.


The main script is put into the sys.modules cache as "__main__", not under
the script's name. Therefore the cache lookup fails.

> So, I think if one evaluated 'myset is __main__', you'd find they are
> exactly the same module under different names; and therefore that
> there is only *one* instance of 'MySet', again under two names.


No:

$ cat tmp.py
import tmp
import __main__

print tmp is __main__

$ python tmp.py
False
False

Peter
 
Reply With Quote
 
Terry Reedy
Guest
Posts: n/a
 
      07-04-2008


Ben Finney wrote:
> Peter Otten <(E-Mail Removed)> writes:
>
>> The problem is the structure of your program. The myset module is
>> imported twice by Python, once as "myset" and once as "__main__".

>
> Yes, this is the problem. Each module imports the other.
>
>> Therefore you get two distinct MySet classes, and consequently two
>> distinct MySet.__instance class attributes.

>
> Are you sure? This goes against my understanding: that 'import foo'
> will not re-import a module that's already been imported, but will
> instead simply return the existing module.


Peter is correct that a module can only be imported once per *name*.
In 3.0b1
temp.py
=================
print(__name__)
import temp
print(__name__)
from sys import modules as m
print(m['__main__'] is m['temp'])

produces
==================
__main__
temp
temp
False
__main__
False

Duplicate imports under multiple names are a known problem, and this is
not the only way to create such. But what can an interpreter do when it
sees 'import x' other than check that 'x' is not already a key in
sys.modules? Iterate through sys.modules (increasingly slow as the dict
grows) and do what exactly? The semantics of 'import x' are to get
sys.modules['x'] if it exists; otherwise 'initialize' module x according
to what that means for the implementation and current state and mode of
operation of the system. Modules are not required to have .__file__
attributes since they do not have to come from named files . (And
then the module is bound to 'x' in the importing namespace.)

Terry Jan Reedy

 
Reply With Quote
 
Urizev
Guest
Posts: n/a
 
      07-05-2008
Great! Thanks everyone for so many references and comments. Lots of
doubts have been solved.

On Fri, Jul 4, 2008 at 10:33 AM, Peter Otten <(E-Mail Removed)> wrote:
> Ben Finney wrote:
>
>> Peter Otten <(E-Mail Removed)> writes:
>>
>>> The problem is the structure of your program. The myset module is
>>> imported twice by Python, once as "myset" and once as "__main__".

>>
>> Yes, this is the problem. Each module imports the other.
>>
>>> Therefore you get two distinct MySet classes, and consequently two
>>> distinct MySet.__instance class attributes.

>>
>> Are you sure? This goes against my understanding: that 'import foo'
>> will not re-import a module that's already been imported, but will
>> instead simply return the existing module.

>
> The main script is put into the sys.modules cache as "__main__", not under
> the script's name. Therefore the cache lookup fails.
>
>> So, I think if one evaluated 'myset is __main__', you'd find they are
>> exactly the same module under different names; and therefore that
>> there is only *one* instance of 'MySet', again under two names.

>
> No:
>
> $ cat tmp.py
> import tmp
> import __main__
>
> print tmp is __main__
>
> $ python tmp.py
> False
> False
>
> Peter
> --
> http://mail.python.org/mailman/listinfo/python-list
>




--
Saludos

Juan Carlos

"ˇˇViva lo rancio!!"
 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Singleton methods without the singleton class Charles Oliver Nutter Ruby 4 03-22-2010 10:46 PM
Singleton object vs. enhancing singleton class Paul McMahon Ruby 3 06-09-2008 06:05 AM
Singleton Modules rather than Singleton Classes Trans Ruby 12 09-14-2007 06:45 AM
Singleton - Whether Cloneable overrides Singleton Proton Projects - Moin Java 4 03-27-2007 02:59 AM
Singleton classes and Singleton pattern Wilhelm Ruby 1 10-11-2006 01:08 PM



Advertisments