Es scheint viele Möglichkeiten der Definition zu geben Einzelnes in Python. Gibt es eine einheitliche Meinung auf Stack Overflow?
Antworten
Zu viele Anzeigen?Le site Python-Dokumentation deckt dies ab:
class Singleton(object):
def __new__(cls, *args, **kwds):
it = cls.__dict__.get("__it__")
if it is not None:
return it
cls.__it__ = it = object.__new__(cls)
it.init(*args, **kwds)
return it
def init(self, *args, **kwds):
pass
Ich würde es wahrscheinlich so umschreiben, dass es mehr wie folgt aussieht:
class Singleton(object):
"""Use to create a singleton"""
def __new__(cls, *args, **kwds):
"""
>>> s = Singleton()
>>> p = Singleton()
>>> id(s) == id(p)
True
"""
it_id = "__it__"
# getattr will dip into base classes, so __dict__ must be used
it = cls.__dict__.get(it_id, None)
if it is not None:
return it
it = object.__new__(cls)
setattr(cls, it_id, it)
it.init(*args, **kwds)
return it
def init(self, *args, **kwds):
pass
class A(Singleton):
pass
class B(Singleton):
pass
class C(A):
pass
assert A() is A()
assert B() is B()
assert C() is C()
assert A() is not B()
assert C() is not B()
assert C() is not A()
Es sollte relativ einfach sein, dies zu erweitern:
class Bus(Singleton):
def init(self, label=None, *args, **kwds):
self.label = label
self.channels = [Channel("system"), Channel("app")]
...
Ich bin mir da sehr unsicher, aber mein Projekt verwendet "Konventionssingletons" (nicht erzwungene Singletons), das heißt, wenn ich eine Klasse namens DataController
Ich definiere dies in demselben Modul:
_data_controller = None
def GetDataController():
global _data_controller
if _data_controller is None:
_data_controller = DataController()
return _data_controller
Er ist nicht elegant, da er ganze sechs Zeilen lang ist. Aber alle meine Singletons verwenden dieses Muster, und es ist zumindest sehr explizit (was pythonisch ist).
Da die akzeptierte Antwort sagt, dass die idiomatischste Art und Weise darin besteht, einfach ein Modul verwenden .
In diesem Sinne, hier ist ein Beweis für das Konzept:
def singleton(cls):
obj = cls()
# Always return the same object
cls.__new__ = staticmethod(lambda cls: obj)
# Disable __init__
try:
del cls.__init__
except AttributeError:
pass
return cls
Siehe die Python-Datenmodell für weitere Informationen über __new__
.
Beispiel:
@singleton
class Duck(object):
pass
if Duck() is Duck():
print "It works!"
else:
print "It doesn't work!"
Notas:
-
Sie müssen New-Style-Klassen verwenden (Ableitung von
object
) für diese. -
Das Singleton wird initialisiert, wenn es definiert wird, und nicht bei der ersten Verwendung.
-
Dies ist nur ein Beispiel für ein Spielzeug. Ich habe nie tatsächlich verwendet diese in der Produktion Code, und nicht planen, zu.