1. 10
  1. 7

    What would be a Pythonic way to implement a singleton-ish pattern?

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

    You may already know this, but that’s not the usual Python way to implement a singleton - usually a singleton is implemented by overriding __new__. This Borg is much less singleton-y because two Borg instances won’t compare as equal.

    Also, singletons are bad http://www.object-oriented-security.org/lets-argue/singletons

    1. 6

      There are cases where you need something like a singleton, but the right way to do that in Python is just to have one named instance in a module, and its “singleness” comes from the fact that you are importing foo from bar, and imports are a shared global namespace.

      1. 3

        The enum module in the standard library is one example where that approach to singletons does not work and you need to override __new__.

      2. 2

        You’re absolutely right: Two borgs don’t compare as equal (using id(borg_1) == id(borg_2)) but everything inside is the same.

        My point was not to make a case for singletons (or borgs) as I outlined in the article:

        Note that you should use singleton classes only occasionally because they introduce some global state in your program, which makes it hard to test individual components of your program in isolation.

        Instead, I wanted to illustrate how Python manages attributes.

      3. 3

        Interesting although I think singletons like this can make unit testing difficult, can’t they?

        1. 3

          Like anything else which holds a global state, yes; borgs make unit testing difficult in the same way as regular singletons do.