2017-08-31 4 views
0

Klassen erben können ..Können Python-Metaklassen erben?

class Base: 
    def __init__(self,name): 
     self.name = name 

class Derived1(Base): 
    def __init__(self,name): 
     super().__init__(name) 


class Derived2(Base): 
    def __init__(self,name): 
     super().__init__(name) 

Kann eine ähnliche Sache auch für die Meta-Klassen gemacht?

Ich habe eine Verpflichtung, wo einige meiner Klassen beide abstrakte Basisklassen sein müssen und auch Klassen meine eigene Meta (sagen Singleton Typen ..)

Ist es möglich,

class Singleton(type): 
    ''' 
    implementation goes here.. 
    ''' 

class AbstractSingleton(Singleton,ABCMeta): 
    ''' 
    What code should go here?? 
    ''' 

zu tun Wenn es möglich ist, die AbstractSingleton-Klasse zu implementieren?

+0

Haben Sie es versucht? Es sollte funktionieren. Ihre Beispielmetaklasse ist nur komplizierter als Ihre normalen Klassen, da sie mehrfache Vererbung verwendet. – Blckknght

+0

nein ich habe nicht .. ich verstehe nicht vollständig, wie die __new__ Methodenaufruf im Falle der metaclass Vererbung angekettet werden und wie ich gefragt habe ich bin mir nicht sicher, welcher Code sollte innerhalb der AbstractSingleton gehen .. –

+0

Solange Sie '' verwenden Super in beiden Metaklassen, es wird wahrscheinlich einfach funktionieren. – Blckknght

Antwort

2

Ja, es ist möglich.

Aber der Reihe nach:

Sie sollte nicht für die Erstellung von Singletons in Python mit metaclasses sein. Singletons sind ein einfaches Konzept, und nur eine benutzerdefinierte __new__ Methode ist genug - keine Notwendigkeit für eine Metaklasse dafür.

Diese einfache 4-zeiliges normalen Code Klasse kann als mixin verwendet werden, und werden alle abgeleiteten Klassen in „Singletons“ Klassen drehen - Afer die erste Instanz erstellt wird, werden keine weiteren Instanzen erstellt, nd die erste Instanz wird immer wieder:

class SingletonBase: 
    def __new__(cls, *args, **kw): 
     if not "instance" in cls.__dict__: 
       cls.instance = super().__new__(cls, *args, **kw) 
     return cls.instance 

Nun, wenn Sie einen echten Fall für einen anderen metaclass haben würde und mit ABCMeta oder anderen metaclass zu kombinieren, was benötigt, zu tun alles, was Sie haben würde, ist eine dritte Metaklasse zu erstellen, erbt von beiden Metaklassen - wenn beide super auf eine gut erzogene Weise verwenden, würde es einfach funktionieren.

class SingletonMeta(type): 
    def __call__(cls, *args, **kw): 
     # You know - you _really_ should not be using metaclasses for singletons. 
     if not "instance" in cls.__dict__: 
      cls.instance = super().__call__(*args, **kw) 
     return cls.instance 


class SingletonAbstractMeta(SingletonMeta, abc.ABCMeta): 
    pass 

class SingleAbstractBase(metaclass=SingleAbstractMeta): 
    ... 

Für puren Zufall, Anfang diese Woche habe ich genau diesen Anwendungsfall als ein Beispiel dafür, was mit einer „Meta-Meta-Klasse“ in Python erreicht werden. Durch die Verwendung einer speziellen "Meta-Metaklasse" zur Metaklasse, die man mit einer anderen kombinieren möchte (ich verwende in diesem Beispiel sogar ABCMeta), kann sie die abgeleitete kombinierte Metaklasse nur mit dem Operator "+" erstellen, wie in

Check the answer here.