Re: Singleton implementation problems

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Peter Otten

    Re: Singleton implementation problems

    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__.Singl eton instance at 0x2b98be474a70>
    New singleton:
    <myset.Singleto n 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.__instanc e
    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

  • Ben Finney

    #2
    Re: Singleton implementation problems

    Peter Otten <__peter__@web. dewrites:
    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.__instanc e 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.

    --
    \ “Science doesn't work by vote and it doesn't work by |
    `\ authority.” —Richard Dawkins, _Big Mistake_ (The Guardian, |
    _o__) 2006-12-27) |
    Ben Finney

    Comment

    • Matthew Fitzgibbons

      #3
      Re: Singleton implementation problems

      Ben Finney wrote:
      Peter Otten <__peter__@web. dewrites:
      >
      >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.__instanc e 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

      Comment

      • Peter Otten

        #4
        Re: Singleton implementation problems

        Ben Finney wrote:
        Peter Otten <__peter__@web. dewrites:
        >
        >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.__instanc e 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

        Comment

        • Terry Reedy

          #5
          Re: Singleton implementation problems



          Ben Finney wrote:
          Peter Otten <__peter__@web. dewrites:
          >
          >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.__instanc e 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

          Comment

          • Urizev

            #6
            Re: Singleton implementation problems

            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 <__peter__@web. dewrote:
            Ben Finney wrote:
            >
            >Peter Otten <__peter__@web. dewrites:
            >>
            >>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.__instanc e 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
            --

            >


            --
            Saludos

            Juan Carlos

            "¡¡Viva lo rancio!!"

            Comment

            Working...