import threading
class Singleton(object):
"""A thread-safe class acting like a singleton"""
_instance = None
_lock = threading.Lock()
def __new__(cls, *args, **kwargs):
if not cls._instance:
with cls._lock:
cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance
import threading
class Singleton(object):
"""A thread-safe class acting like a singleton"""
_instance = None
_lock = threading.Lock()
def __new__(cls, *args, **kwargs):
with cls._lock:
if not cls._instance:
cls._instance = object.__new__(cls, *args, **kwargs)
return cls._instance
Zuletzt geändert von Defnull am Donnerstag 3. September 2009, 20:18, insgesamt 1-mal geändert.
Ein Singleton ist das einzige Exemplar einer Klasse. Oder anders ausgedrückt, alle Exemplare der Klasse sind nicht nur gleich sondern auch identisch.
Und threadsafe ist nicht das Singleton-Objekt, sondern der Konstruktor `__new__` der beim ersten Aufruf das Objekt erzeugt - genau einmal und nicht öfters.
Ist es eigentlich sinnvoll, dass ein Singleton Argumente annehmen kann? Denn schließlich verschwinden ja jegliche Argumente, die nach dem ersten Bau übergeben werden, ohnehin sang- und klanglos im Nirvana. Ist es vielleicht besser, einen anderen Weg zu gehen und eine Exception zu werfen, sobald versucht wird, ein Singleton zum zweiten Mal zu instanzieren? Welcher Weg wäre hier zu bevorzugen?
@Chrisber: Und um das gerade Erläuterte zu gewährleisten, ist der Trick hier, dass sich sozusagen in den Erstellungsprozess der Klasse eingemischt wird. Es wird diesmal nicht mit den Attributen des Exemplars gearbeitet, wie man es häufig in der __init__-Methode einer Klasse findet, sondern direkt mit den Klassenattributen. Die überschriebene __new__-Methode, welche noch vor __init__ aufgerufen wird, prüft, ob bereits ein Exemplar erstellt wurde. Wenn nicht, wird eins erstellt und an das Attribut _instance gebunden und dieser Wert gilt nun dauerhaft. Falls es schon ein Exemplar gibt - _instance also nicht mehr mit None belegt ist -, passiert nichts und es bleibt somit beim zuerst erstellten Exemplar. Zuletzt wird dieses dann zurückgeliefert.
class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
if args or kwargs:
raise TypeError, 'Singleton does not take any argument'
if not cls._instance:
cls._instance = object.__new__(cls)
return cls._instance