Was ist der beste Weg, um einen Singleton in Python umzusetzen?Python

Python-Programme
Anonymous
 Was ist der beste Weg, um einen Singleton in Python umzusetzen?

Post by Anonymous »

Ich habe mehrere Klassen, die Singletons werden würden (mein Anwendungsfall ist für einen Logger, aber das ist nicht wichtig). Ich möchte mehrere Klassen nicht mit zusätzlichem Gumph überladen, wenn ich einfach erben oder dekorieren kann.

Code: Select all

def singleton(class_):
instances = {}
def getinstance(*args, **kwargs):
if class_ not in instances:
instances[class_] = class_(*args, **kwargs)
return instances[class_]
return getinstance

@singleton
class MyClass(BaseClass):
pass
< /code>
Pros < /p>
[list]
[*] Dekoratoren sind in einer Weise additiv, die oft intuitiver ist als multiple Vererbung. MyClass 
selbst ist eine Funktion, keine Klasse, daher können Sie keine Klassenmethoden daraus aufrufen. Auch für < /p>

Code: Select all

x = MyClass();
y = MyClass();
t = type(n)();
< /code>
< /li>
< /ul>
Dann x == y < /code> Aber x! = T && y!class Singleton(object):
_instance = None
def __new__(class_, *args, **kwargs):
if not isinstance(class_._instance, class_):
class_._instance = object.__new__(class_, *args, **kwargs)
return class_._instance

class MyClass(Singleton, BaseClass):
pass
< /code>
Profis < /p>

 Es ist eine echte Klasse < /li>
< /ul>
cons < /p>

 Multiple Erbe - Eugh! __new __ 
könnte während der Erbschaft aus einer zweiten Basisklasse überschrieben werden? Man muss mehr denken als nötig.

Code: Select all

class Singleton(type):
_instances = {}
def __call__(cls, *args, **kwargs):
if cls not in cls._instances:
cls._instances[cls] = super(Singleton, cls).__call__(*args, **kwargs)
return cls._instances[cls]

#Python2
class MyClass(BaseClass):
__metaclass__ = Singleton

#Python3
class MyClass(BaseClass, metaclass=Singleton):
pass
Pros

It's a true class
[*]Auto-magically covers inheritance
[*]Uses __metaclass__ for its proper purpose (and made me aware of it)
[/list]
cons < /p>

[*] Gibt es irgendwelche?

Code: Select all

def singleton(class_):
class class_w(class_):
_instance = None
def __new__(class_, *args, **kwargs):
if class_w._instance is None:
class_w._instance = super(class_w,
class_).__new__(class_,
*args,
**kwargs)
class_w._instance._sealed = False
return class_w._instance
def __init__(self, *args, **kwargs):
if self._sealed:
return
super(class_w, self).__init__(*args, **kwargs)
self._sealed = True
class_w.__name__ = class_.__name__
return class_w

@singleton
class MyClass(BaseClass):
pass
< /code>
Profis < /p>

 Es ist eine echte Klasse < /li>
 automatisch bedeckt die Erbschaft < /li>
< /ul>
Hier erstellen wir zwei Klassen für jede Klasse, die wir einen Singleton machen möchten. Obwohl dies in meinem Fall in Ordnung ist, mache ich mir Sorgen, dass dies möglicherweise nicht skaliert wird. Natürlich gibt es eine Frage der Debatte darüber, ob es etwas zu einfach ist, dieses Muster zu skalieren ...
[*] Was ist der Sinn des _Sealed 
Attribut
Ich kann nicht auf dem gleichnamigen Namen in Basisklassen mit Super () können, weil sie sich wiederholen. Dies bedeutet, dass Sie __New __ nicht anpassen können und eine Klasse, in der Sie __init __ aufrufen müssen. /> Profis < /p>

Einfach ist besser als komplex < /li>
< /ul>
cons < /p>

Nicht -faule -instantiiert < /li>

Quick Reply

Change Text Case: 
   
  • Similar Topics
    Replies
    Views
    Last post