mailRe: The singleton design pattern for the old 'self.relax.data' data structure.


Others Months | Index by Date | Thread Index
>>   [Date Prev] [Date Next] [Thread Prev] [Thread Next]

Header


Content

Posted by Edward d'Auvergne on March 08, 2007 - 10:33:
On 3/8/07, Gary S. Thompson <garyt@xxxxxxxxxxxxxxx> wrote:
Chris MacRaild wrote:

>On Wed, 2007-03-07 at 19:06 +1100, Edward d'Auvergne wrote:
>
>
>
>>Hi,
>>
>>After careful thought about design patterns, I've decided to try to
>>use the singleton pattern for the old 'self.relax.data' data
>>structure.  See http://en.wikipedia.org/wiki/Singleton_pattern for
>>more information about this design pattern.  I'll try to use the
>>second simple example under the heading 'Python Borg pattern'.  The
>>benefit of this pattern is that each module can use the code:
>>
>>from data import Data
>>relax_data = Data()
>>
>>As Data will be a singleton if two modules used by relax instantiate
>>the Data class then the global 'relax_data' in both modules will be
>>the same instance.  Therefore if a method from the
>>'special_fns.model_free' module modifies the data structure, all the
>>other relax modules using the singleton will see the changes.  The
>>benefit of this pattern is that the data structure is similar in
>>concept to a global variable but only modules utilising it will have
>>it in one of their namespaces.  Also 'self.relax.data' will not need
>>to be passed around inside the program, simplifying the code.  What do
>>you think of the idea?
>>
>>
>
>One issue here, identified on the wikipedia page, is that __init__() is
>called for each call of Singleton(). Therefore all of the standard
>__init__() stuff - inialising variables and empty containers - will
>happen every time the Singleton instance is sought. This is clearly not
>what we want. Ofcourse there are many ways around that by cleverly
>hiding the initialisation stuff, but its starting to look like a complex
>solution to what should be a simple problem.
>
>Something like:
>
>class Data:
>    ...
>Data = Data()
>
>in the data module, then everywhere else:
>
>from data import Data as relax_data
>
>
>By rebinding the name 'Data' with an instance of the class, we
>effectively prevent accidental creation of additional instances, and the
>import makes that instance availible wherever we need it.
>
>Chris
>
>
>
I agree

another alternative would be a more classic singleton such as


class _Singleton(object):

    def __init__(self):
        # just for the sake of information
        self.instance = "Instance at %d" % self.__hash__()


_singleton = _Singleton()

def Singleton(): return _singleton

=====

>>> from singleton import Singleton
>>> s1 = Singleton()
>>> s2 = Singleton()
>>> s1.instance
'Instance at -1226695220'
>>> s2.instance
'Instance at -1226695220'
>>> s1 == s2
True

which is from the discussion on
http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/52558

Although using slightly different approach from the code currently in the 1.3 line the end result is identical in both implementations. In the above example the instance reference is stored in the global namespace of the module whereas in the file 'data/__init__.py' the instance reference is stored in the scope of the Data class. Both the __new__() method and the Singleton() function then return that reference to the import statement. From the point of view of the rest of relax, the import and initiation is identical. Gary, do you see a benefit from using the alternative example?

Cheers,

Edward



Related Messages


Powered by MHonArc, Updated Thu Mar 08 11:00:23 2007