554 Stimmen

Gibt es eine einfache, elegante Möglichkeit, Singletons zu definieren?

Es scheint viele Möglichkeiten der Definition zu geben Einzelnes in Python. Gibt es eine einheitliche Meinung auf Stack Overflow?

442voto

Staale Punkte 25764

Ich sehe nicht wirklich die Notwendigkeit, da ein Modul mit Funktionen (und nicht eine Klasse) gut als Singleton dienen würde. Alle seine Variablen wären an das Modul gebunden, das ohnehin nicht wiederholt instanziiert werden könnte.

Wenn Sie eine Klasse verwenden möchten, gibt es in Python keine Möglichkeit, private Klassen oder private Konstruktoren zu erstellen, so dass Sie sich nicht gegen mehrfache Instanziierungen schützen können, außer durch Konventionen bei der Verwendung Ihrer API. Ich würde trotzdem nur Methoden in ein Modul packen und das Modul als Singleton betrachten.

374voto

Paul Manta Punkte 29251

Hier ist meine eigene Implementierung von Singletons. Alles, was Sie tun müssen, ist, die Klasse zu dekorieren; um das Singleton zu erhalten, müssen Sie dann die Instance Methode. Hier ist ein Beispiel:

@Singleton
class Foo:
   def __init__(self):
       print 'Foo created'

f = Foo() # Error, this isn't how you get the instance of a singleton

f = Foo.instance() # Good. Being explicit is in line with the Python Zen
g = Foo.instance() # Returns already created instance

print f is g # True

Und hier ist der Code:

class Singleton:
    """
    A non-thread-safe helper class to ease implementing singletons.
    This should be used as a decorator -- not a metaclass -- to the
    class that should be a singleton.

    The decorated class can define one `__init__` function that
    takes only the `self` argument. Also, the decorated class cannot be
    inherited from. Other than that, there are no restrictions that apply
    to the decorated class.

    To get the singleton instance, use the `instance` method. Trying
    to use `__call__` will result in a `TypeError` being raised.

    """

    def __init__(self, decorated):
        self._decorated = decorated

    def instance(self):
        """
        Returns the singleton instance. Upon its first call, it creates a
        new instance of the decorated class and calls its `__init__` method.
        On all subsequent calls, the already created instance is returned.

        """
        try:
            return self._instance
        except AttributeError:
            self._instance = self._decorated()
            return self._instance

    def __call__(self):
        raise TypeError('Singletons must be accessed through `instance()`.')

    def __instancecheck__(self, inst):
        return isinstance(inst, self._decorated)

225voto

jojo Punkte 3464

Sie können die __new__ Methode wie folgt:

class Singleton(object):
    _instance = None
    def __new__(cls, *args, **kwargs):
        if not cls._instance:
            cls._instance = super(Singleton, cls).__new__(
                                cls, *args, **kwargs)
        return cls._instance

if __name__ == '__main__':
    s1 = Singleton()
    s2 = Singleton()
    if (id(s1) == id(s2)):
        print "Same"
    else:
        print "Different"

133voto

Peter Hoffmann Punkte 52200

Ein etwas anderer Ansatz zur Implementierung des Singletons in Python ist die Borg-Muster von Alex Martelli (Google-Mitarbeiter und Python-Genie).

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

Anstatt also alle Instanzen zu zwingen, dieselbe Identität zu haben, teilen sie sich den Status.

92voto

Acuminate Punkte 1236

Der modulare Ansatz funktioniert gut. Wenn ich unbedingt ein Singleton brauche, bevorzuge ich den Metaklassen-Ansatz.

class Singleton(type):
    def __init__(cls, name, bases, dict):
        super(Singleton, cls).__init__(name, bases, dict)
        cls.instance = None 

    def __call__(cls,*args,**kw):
        if cls.instance is None:
            cls.instance = super(Singleton, cls).__call__(*args, **kw)
        return cls.instance

class MyClass(object):
    __metaclass__ = Singleton

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X