Frage

Ich habe einige Tutorials auf Python metaclasses lesen. Ich habe ein noch nie benutzt, aber ich brauche einen für etwas relativ einfach und all die Tutorials scheinen zu viel komplexere Anwendungsfälle ausgerichtet. Ich mag im Grunde eine Template-Klasse erstellen, die einen vorher festgelegten Körper hat, sondern seine Basisklasse als Parameter. Da ich die Idee von C ++ / D-Vorlagen bekommen, hier ist ein Beispiel dessen, was der Code, den ich schreiben will, wie in C ++ aussehen würde:

template<class T>
    class Foo : T {
        void fun() {}
    }
War es hilfreich?

Lösung

Obwohl es kann sicherlich mit metaclasses getan werden, können Sie tun, was Sie, ohne sie zu wollen, weil in Python-Klassen sind selbst Objekte. Die Mittel, die-raschend-im Wesentlichen nichts anderes als eine fast Eins-zu-Eins-Übersetzung des C ++ Code erforderlich ist. Neben relativ, weil dieser unkompliziert ist, Arbeit, es wird auch ohne Änderungen sowohl in Python 2 & 3.

def template(class_T):
    """Factory function to create subclasses of class_T."""

    class Foo(class_T):
        def fun(self):
            print('%s.fun()' % self.__class__.__name__)

    Foo.__name__ += '_' + class_T.__name__  # rename the subclass to reflect its heritage
    return Foo

class Base1:
    def bar(self):
        print('Base1.bar()')

class Base2:
    def bar(self):
        print('Base2.bar()')

Foo_Base1 = template(Base1)
print('Foo_Base1 base classes: {}'.format(Foo_Base1.__bases__))

Foo_Base2 = template(Base2)
print('Foo_Base2 base classes: {}'.format(Foo_Base2.__bases__))

subclass1 = Foo_Base1()
subclass1.fun()
subclass1.bar()
subclass2 = Foo_Base2()
subclass2.fun()
subclass2.bar()

Ausgabe:

Foo_Base1 base classes: (<class __main__.Base1 at 0x00A79C38>,)
Foo_Base2 base classes: (<class __main__.Base2 at 0x00A79DC0>,)
Foo_Base1.fun()
Base1.bar()
Foo_Base2.fun()
Base2.bar()

Der Code in der (unimaginatively genannten) template() Funktion ist ein Beispiel, was man gemeinhin ein Class Factory oder eine Implementierung des Fabrikmuster . Also, nebenbei bemerkt, könnten Sie feststellen, "https://stackoverflow.com/questions / 2526879 / what-genau-is-a-Klasse-Fabrik "> Was genau ist eine Klasse-Fabrik? informativ.

Edit: Code hinzugefügt verschiedene Klassennamen erstellen für jede Unterklasse zurück-die von @ inspiriert aaronasterling 's Einblick (in einem jetzt gelöscht Kommentar) über eine mögliche Verwirrung beim Debuggen, wenn die Klasse hergestellt immer den gleichen Namen hat.

Andere Tipps

Das ist sinnlos in Python, da es keine Vorlagen hat. Mein Verständnis von parametrisiert Vorlagen in C ++ (die eher vage ist, da es viele Jahre her, seit ich sie ausgesehen haben), ist, dass es wie ein Klassengenerator fungiert, und eine Unterklasse von was auch immer Klasse erstellen, können Sie es geben, dass zusätzliche Methoden hat oder Attribute hinzugefügt.

In Python Sie können dies tun, mit einer Fabrik-Funktion, die eine Klasse nimmt und gibt eine neue Klasse zur Laufzeit:

In [1]: def subclassFactory(cls):
   ...:     class Foo(cls):
   ...:         def fun(self):
   ...:             return "this is fun"
   ...:     return Foo
   ...: 

In [2]: class A(object):
   ...:     pass
   ...: 

In [5]: C = subclassFactory(A)

In [6]: C
Out[6]: <class '__main__.Foo'>
In [7]: c = C()
In [9]: c.fun()
Out[9]: 'this is fun'
In [10]: isinstance(c, A)
Out[10]: True
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top