Es scheint viele Möglichkeiten der Definition zu geben Einzelnes in Python. Gibt es eine einheitliche Meinung auf Stack Overflow?
Antworten
Zu viele Anzeigen?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.
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)
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"
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.
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
- See previous answers
- Weitere Antworten anzeigen