0

I was looking over the Singleton design pattern in Python here: http://python-3-patterns-idioms-test.readthedocs.io/en/latest/Singleton.html

class OnlyOne:
    class __OnlyOne:
        def __init__(self, arg):
            self.val = arg
        def __str__(self):
            return repr(self) + self.val
    instance = None
    def __init__(self, arg):
        if not OnlyOne.instance:
            OnlyOne.instance = OnlyOne.__OnlyOne(arg)
        else:
            OnlyOne.instance.val = arg
    def __getattr__(self, name):
        return getattr(self.instance, name)

I was thinking that in Java the Singleton pattern is implemented using a private constructor.

However, there is no private constructor in the code above and as I understand it, there are no private methods in Python.

So if you want to implement Singleton, how can you prevent someone from instantiating a class multiple times?

bsky
  • 19,326
  • 49
  • 155
  • 270
  • 1
    In Python you can override `__new__` so that it returns an existing object when someone tries to instantiate it. One of the example you linked to actually does that, though not the one you quoted. – khelwood Nov 04 '16 at 11:03
  • It's more of an agreement that you shall not directly call methods like `__foo__` or classes like `__Foo` because [they are assumed to be private](https://stackoverflow.com/questions/1641219/does-python-have-private-variables-in-classes) – Cory Kramer Nov 04 '16 at 11:04
  • 2
    Ugh, that is a bad implementation of a singleton in python. A proper one would be using ``__new__`` as @khelwood suggested. – Jonas Schäfer Nov 04 '16 at 11:05
  • @CoryKramer Not quite. The agreement concerns attributes that have a _single_ leading underscore; see http://stackoverflow.com/q/1301346/4014959 – PM 2Ring Nov 04 '16 at 11:15

2 Answers2

2

The code you've posted has instance which is a class member. Since __init__ checks this class member, you may have multiple OnlyOne instances but they all share the same __OnlyOne instance.

0

There will be several different instances of OnlyOne.

However, there is only one instance of the inner class, __OnlyOne, that is stored as a class variable on OnlyOne.

All attribute lookups on OnlyOne instances actually return the value of the attribute of the __OnlyOne instance (that's what the __getattr__ method does).

I have never seen this pattern used, typically people make a singleton by making a module global variable that is the single instance, and then just use that everywhere.

RemcoGerlich
  • 30,470
  • 6
  • 61
  • 79