Marco Pesenti Gritti <mpg <at> redhat.com> writes:
> we should probably settle on a consistent implementation for singletons.
> This is what we have in the ps:
> _ps = None
> def get_instance():
> global _ps
> if not _ps:
> _ps = PresenceService()
> return _ps
> and PresenceService.get_instance() to get it.
If using this pattern, you should is "if _ps is None" and PresenceService
should be named _PresenceService (because it is private). If you don't need
to instantiate the object lazily, you should do:
presence_service = _PresenceService()
at the module level, and then presence_service is the singleton (and you
won't instantiate other instances unless you go out of your way to get the
If you really want lazy instantiation, I prefer a factory function like
> In the icon cache:
> class IconCache(gobject.GObject):
> __metaclass__ = GObjectSingletonMeta
> using this from sugar.util
> class GObjectSingletonMeta(gobject.GObjectMeta):
> """GObject Singleton Metaclass"""
> def __init__(klass, name, bases, dict):
> gobject.GObjectMeta.__init__(klass, name, bases, dict)
> klass.__instance = None
> def __call__(klass, *args, **kwargs):
> if klass.__instance is None:
> klass.__instance = gobject.GObjectMeta.__call__(klass,
> *args, **kwargs)
> return klass.__instance
> and you can use the normal constructor.
The arguments get ignored if the singleton has already been created; that's
no good. Either there should be zero arguments, or it shouldn't be a
Incidentally, you can also make a class a singleton (or instances unique
based on the constructor parameters) by overriding __new__ (instead of the
metaclass's __call__), though I don't know if one is better than the other.
The metaclass is probably better, because __new__ has some quirky behavior with
respect to __init__.
I personally don't care for the Borg pattern; module-level instantiation is
usually the right thing to do, and a factory function is very easy to
understand otherwise. Also, instances with a shared __dict__ are a little
crazy. Mostly singleton patterns involve over-design IMHO -- there's several
situations that call for different implementations, and all they have in
common is that in some languages those different things are all implemented
with singletons, even though that might not be appropriate in Python.