Es scheint viele Möglichkeiten der Definition zu geben Einzelnes in Python. Gibt es eine einheitliche Meinung auf Stack Overflow?
Antworten
Zu viele Anzeigen?OK, Singleton kann gut oder böse sein, ich weiß. Dies ist meine Implementierung, und ich erweitere einfach einen klassischen Ansatz, um einen Cache im Inneren einzuführen und viele Instanzen eines anderen Typs oder viele Instanzen desselben Typs, aber mit unterschiedlichen Argumenten zu erzeugen.
Ich habe es Singleton_group genannt, weil es ähnliche Instanzen zusammenfasst und verhindert, dass ein Objekt der gleichen Klasse mit den gleichen Argumenten erstellt werden kann:
# Peppelinux's cached singleton
class Singleton_group(object):
__instances_args_dict = {}
def __new__(cls, *args, **kwargs):
if not cls.__instances_args_dict.get((cls.__name__, args, str(kwargs))):
cls.__instances_args_dict[(cls.__name__, args, str(kwargs))] = super(Singleton_group, cls).__new__(cls, *args, **kwargs)
return cls.__instances_args_dict.get((cls.__name__, args, str(kwargs)))
# It's a dummy real world use example:
class test(Singleton_group):
def __init__(self, salute):
self.salute = salute
a = test('bye')
b = test('hi')
c = test('bye')
d = test('hi')
e = test('goodbye')
f = test('goodbye')
id(a)
3070148780L
id(b)
3070148908L
id(c)
3070148780L
b == d
True
b._Singleton_group__instances_args_dict
{('test', ('bye',), '{}'): <__main__.test object at 0xb6fec0ac>,
('test', ('goodbye',), '{}'): <__main__.test object at 0xb6fec32c>,
('test', ('hi',), '{}'): <__main__.test object at 0xb6fec12c>}
Jedes Objekt trägt den Singleton-Cache... Dies könnte böse sein, aber es funktioniert gut für einige :)
class Singeltone(type):
instances = dict()
def __call__(cls, *args, **kwargs):
if cls.__name__ not in Singeltone.instances:
Singeltone.instances[cls.__name__] = type.__call__(cls, *args, **kwargs)
return Singeltone.instances[cls.__name__]
class Test(object):
__metaclass__ = Singeltone
inst0 = Test()
inst1 = Test()
print(id(inst1) == id(inst0))
Da ich relativ neu in Python bin, bin ich mir nicht sicher, was das gängigste Idiom ist, aber das Einfachste, was mir einfällt, ist die Verwendung eines Moduls anstelle einer Klasse. Was in Ihrer Klasse Instanzmethoden gewesen wären, werden im Modul zu Funktionen, und alle Daten werden im Modul zu Variablen, anstatt zu Mitgliedern der Klasse. Ich vermute, dass dies der pythonische Ansatz ist, um die Art von Problemen zu lösen, für die Leute Singletons verwenden.
Wenn Sie wirklich eine Singleton-Klasse wollen, gibt es eine vernünftige Implementierung, die in der erster Treffer bei Google für "Python Singleton", genauer gesagt:
class Singleton:
__single = None
def __init__( self ):
if Singleton.__single:
raise Singleton.__single
Singleton.__single = self
Das scheint zu genügen.
Singletons Halbbruder
Ich stimme staale voll und ganz zu und hinterlasse hier ein Beispiel für die Erstellung eines einzigen Halbbruders:
class void:pass
a = void();
a.__class__ = Singleton
a
meldet nun, dass es zur gleichen Klasse wie Singleton gehört, auch wenn es nicht so aussieht. So Singletons mit komplizierten Klassen am Ende abhängig von wir nicht viel mit ihnen verwirren.
Da dies so ist, können wir den gleichen Effekt erzielen und einfachere Dinge wie eine Variable oder ein Modul verwenden. Wenn wir jedoch aus Gründen der Klarheit Klassen verwenden wollen und weil in Python ist eine Klasse ein Objekt Wir haben also bereits das Objekt (nicht und Instanz, aber es wird genau so tun).
class Singleton:
def __new__(cls): raise AssertionError # Singletons can't have instances
Dort haben wir einen netten Assertion-Fehler, wenn wir versuchen, eine Instanz zu erstellen, und wir können auf Ableitungen statische Mitglieder speichern und Änderungen an ihnen zur Laufzeit vornehmen (ich liebe Python). Dieses Objekt ist so gut wie andere Halbbrüder (Sie können sie immer noch erstellen, wenn Sie möchten), aber es wird aufgrund der Einfachheit tendenziell schneller laufen.