Singleton class: what is the purpose?

Dave Harrison dave at nullcube.com
Thu Jun 5 07:49:49 EDT 2003


Hi Gerrit,

A Singleton is a very common design pattern (see "Design Patterns : Elements of Reusable Object-Oriented Software" by Gamma et al).

To quote the books quick description :
"Ensure a class only has one instance, and provide a global point of access
to it"

Essentially if you have a database, and you have to access it repeatedly,
you want to make sure you dont update from one direction while another direction
is trusting on that data still being the same while it does something else.

Eg. You have a database object.  You are in the process of updating a record
based on what is in record #43.  You are fiddling with that entry.

At the same time, another client in the same system has also pulled the record and done something else.

You write your data back, just before the other person writes theirs back.  Yours gets overwritten.

If you had a singleton, you would both be accessing the same database, and this problem would not have occurred because you would have known the other person had already checked that record out (since you were both using the same connection to the database instead of seperate ones).

The same can go for file writing and any other time you want to make sure everything is using the same instance of an object.

A neat extension of this is the borg pattern as outlines in the Python Cookbook.

The code (as show to me by a friend) is below .. I hope that friend
doesn't mind me posting it.  The code was a quick hack in a coffee shop
to demonstrate the borg to me.  The design was for a packet sniffer
incidentally.

----------------------------------------------
#!/usr/bin/env python2.2

class Borg:
    _state = {}
    def __init__(self):
        self.__dict__ = self._state

class Parser(Borg):
    def __init__(self):
        Borg.__init__(self)
        self._components = []

    def addComponent(self, componentClass):
        self._components.append(componentClass)

    def accept(cls, packet):
        if packet[0] == cls.NAME:
            return 1
        else:
            return 0
    accept=classmethod(accept)

    def parse(self, packet):
        print self.NAME, "parsing ", packet
        for i in self._components:
            if i.accept(packet[1:]):
                parser = i()
                parser.parse(packet[1:])

class UDP(Parser):
    NAME = "UDP"
    def __init__(self):
        Parser.__init__(self)

class TCP(Parser):
    NAME = "TCP"
    def __init__(self):
        Parser.__init__(self)

class IP(Parser):
    NAME = "IP"
    def __init__(self):
        Parser.__init__(self)
        self.addComponent(IP)
        self.addComponent(TCP)
        self.addComponent(UDP)

class Ethernet(Parser):
    NAME = "Ethernet"
    def __init__(self):
        Parser.__init__(self)
        self.addComponent(IP)

x = Ethernet()
packet = ["Ethernet", "IP", "IP", "TCP"]
x.parse(packet)
----------------------------------------------

As you can see, the packet list is retaining state between instantiations
of the class.  Its a tiny bit of black magic since you are fooling
with the state dictionary.  But very useful.

Hope that helps.

Dave
http://www.nullcube.com

Gerrit Holl (gerrit at nl.linux.org):
> Hi,
> 
> Guido's article on unifying types and classes mentions singleton classes.
> It says:
> 
> """
> As another example of __new__, here's a
> way to implement the singleton pattern.
> """
> (http://www.python.org/2.2.3/descrintro.html)
> 
> What is a singleton class? What is the purpose of a singleton class?
> 
> On the web, I have found that a singleton class allows only one instance.
> Is that correct? If so, it should be easily implementable with:
> 
>  20 >>> class Singleton(object):
>  20 ...  instances = []
>  20 ...  def __init__(self):
>  20 ...   if len(self.__class__.instances) == 0:
>  20 ...    self.__class__.instances.append(self)
>  20 ...   else:
>  20 ...    raise Exception("No way jose!")
>  20 ... # to do it correct, I think getrefcount would me neccesary
>  53 >>> Singleton()
> <__main__.Singleton object at 0x403afe4c>
>  54 >>> Singleton()
> Traceback (most recent call last):
>   File "<stdin>", line 1, in ?
>   File "<stdin>", line 7, in __init__
> Exception: No way jose!
>  55 >>> del Singleton.instances[0] # delete the last reference to the object
>  56 >>> Singleton()
> <__main__.Singleton object at 0x403affac>
> 
> But what is the purpose of a Singleton class?
> 
> yours,
> Gerrit.
> 
> -- 
> 203. If a free-born man strike the body of another free-born man or
> equal rank, he shall pay one gold mina.
>         -- 1780 BC, Hammurabi, Code of Law
> --
> Asperger Syndroom - een persoonlijke benadering:
> 	http://people.nl.linux.org/~gerrit/
> Het zijn tijden om je zelf met politiek te bemoeien:
> 	http://www.sp.nl/
> 
> -- 
> http://mail.python.org/mailman/listinfo/python-list





More information about the Python-list mailing list