singletons

castironpi castironpi at gmail.com
Wed Jul 16 20:00:10 EDT 2008


On Jul 16, 5:20 pm, Craig Allen <callen... at gmail.com> wrote:
> Hey, forgive me for just diving in, but I have a question I was
> thinking of asking on another list but it really is a general question
> so let me ask it here.  It's about how to approach making singletons.
> Background: I've been programming in python seriously for about a year
> now, maybe a little longer depending how you count, and the system I
> am making is sophisticated enough that I've had to enter into a few
> idioms which were beyond my knowledge of python, and I had to do quick
> research and test my ideas with test code (which of course can miss
> subtle problems).  Otoh, I have decades of programming experience now
> and wasn't totally without footing.  I think I have a solution I like
> for creating something to act as a singleton but I'm curious what
> other's think.
>
> I have several classes in our system which need to act like
> singletons, they are libraries of data classifications, and other such
> libraries of configurations for the system which need to be global.
>
> The first thing I found searching for singleton, early in this
> project, trying to be a good citizen and find a decent idiom from the
> python community itself, knowing someone had mentioned "singleton" and
> "python" together at some point, was a recommendation to do this:
>
> (option 1)
>
> class TehLibrary(object):
>    __single = None
>    def __init__(self):
>       if (TehLibrary.__single):
>          raise AlreadyExistsException # or whatever
>
> This sucks because that means creation of the object has to be in a
> try block as a matter of course, something I promptly hid in a factory
> function, but still.
>
> But the way this worked made me realize that the Class itself is a
> full fledged object, quite instance-like from my C++ addled (I love
> you C++) perspective and it's single.  If I can store that instance, I
> can make a class that shares member at the class level. The class
> doesn't even have to be a singleton exactly.
>
> (option 2)
> Therefore option two is a family of options where class level members
> can be used to share whatever needs to be shared, though strictly the
> class is not a singleton since multiple instances are created which
> merely share the data that should be single (say a big dictionary of
> configuration information the class manages).
>
> (option 3)
> I still wanted actual singletons and realized that since I had to
> create a factory function even in option 1, that I could use module
> level variables to control the behavior of those factories, which led
> me to realize I'm basically just using the module itself as a
> singleton. And this is sort of where I have arrived... when I import
> the modules it runs code to build up it's basic services, much like an
> object construction.  It only runs once no matter how many times it's
> imported. When client code asks for the library that should be a
> singleton, it gets a singleton which has been stored in a module level
> variable.
>
> Anyone have any comments?  Is there anything wrong, evil, or ugly
> about using a module this way, or am I correct to think that actually,
> this is a common approach in python.
>
> Is it pythonic?

In option 1, you could use the __new__ method, and return the existing
instance if there is one, or, I believe, call __init__ on the
superclass.  Alternatively, define your own 'create' method with the
@classmethod decorator, instantiate with ClassA.create( ), and return
any existing instance from there.  The catch is you need to rely on
the discipline of not using the default instantiation syntax.

In option 2, you would have to wrap the functions with the
@staticmethod decorator, and all instance methods would act on the
same object.

Each of these have different consequences for inheritance, if that is
on the horizon in your project.



More information about the Python-list mailing list