2017-03-01 3 views
0

Ich habe den Eindruck, dass ich mit Singleton-Muster die Anzahl der Instanziierung einer Klasse auf ein Objekt beschränken kann. Und das im Auge behalten, haben einen Blick auf den Code unten:Singleton-Muster in Basisklasse-Unterklasse-Szenario

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] 

class base1(object): 
    __metaclass__ = Singleton 

class base2(base1): 
    pass 

class base3(base1): 
    pass 

class base4(base2): 
    pass   

obj1 = base4() 
obj2 = base4() 

print obj1 is obj2 #prints True 

obj3 = base3() 
obj4 = base3() 

print obj3 is obj4 #prints True 

print obj1 is obj3 #prints False 

Erste Ausgabe Gedruckte Anweisung druckt True, die beweist, dass obj3 und obj4 sind gleiche Objekt. Aber die zweite Druckanweisung druckt False, die obj1 und obj3 sind nicht dasselbe. Was könnte der beste Weg sein, um das Ziel zu erreichen, "Always return the same base1 object no matter which sub class instantiates it".

+0

Warum würden Sie auch diese Unterklassen haben? Verdammt, warum willst du überhaupt diese Unterklassen existieren lassen, wenn du wirklich den metaklassenbasierten Erzwingungsweg von Singletons durchgehen willst? – user2357112

+0

Das ergibt keinen Sinn! Warum erstellen Sie sogar mehrere Klassen, wenn alle nur ein Objekt ihrer Basis erstellen können? Möchtest du vielleicht einen Alias ​​für die Basisklasse? Ihr Code wurde speziell so erstellt, dass für jede ** Klasse in der Hierarchie ein Singleton ** zulässig ist. Warum hast du es so programmiert? – Wombatz

Antwort

-1

Der Code wurde von here kopiert.

Sie können eine terminal Klasse erstellen und es als __metaclass__ so anderen Klassen können von ihm nicht erben:

class terminal(type): 
    def __init__(self, cl_name, bases, namespace): 
     for cls in bases: 
      if isinstance(cls, terminal): 
       raise TypeError("in "+cl_name+" definition : "+str(cls)+ 
           " can't be used as a base class") 
     super(terminal, self).__init__(cl_name, bases, namespace) 


# first we create a normal class 
class a(object): 
    pass 

#the terminal class: it can inherit from other classes but can't be 
#used as base class 
class b(a): 
    __metaclass__= terminal 

#this will fail because inheriting from b is forbidden 
class c(b): 
    pass 
+0

Wann genau ist diese "Kompilierzeit"? Die Klassenerstellung erfolgt zur Laufzeit! – Wombatz

+0

@Wombatz Code Kommentar - behoben. Kannst du mir sonst noch erklären, warum es keine gute Antwort ist? – alfasin

Verwandte Themen