Choć na pewno można zrobić z metaclasses, możesz robić, co chcesz bez nich, ponieważ w Pythonie klasy same są obiektami. Oznacza to, że - zaskakująco - w zasadzie nic więcej niż prawie jeden do jednego tłumaczenie kodu C++ jest wymagane. Poza tym jest stosunkowo nieskomplikowane z tego powodu, to będzie również działać bez modyfikacji zarówno w Pythonie 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()
wyjściowa:
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()
Kod w (unimaginatively nazwanej) template()
funkcji jest przykład tego, co zwykle nazywa się class factory lub implementacją fabrycznego wzorca . Tak więc, nawiasem mówiąc, możesz znaleźć my answer na pytanie What exactly is a Class Factory? informacyjny.
Edit: Kod Dodany do tworzenia różnych nazw klas dla każdej podklasy zwróconego-który został zainspirowany @ „s aaronasterling wglądu (w obecnie usunięty komentarz) na temat potencjalnego zamieszania podczas debugowania, jeśli klasa produkowane zawsze ma taką samą nazwę .
Awesome, Chyba metaclasses są przesadą czegoś tak prostego. To rozwiązanie sprawia, że z perspektywy czasu jest mnóstwo sensu, ponieważ typy są obiektami pierwszej klasy w Pythonie, a klasy można tworzyć w czasie wykonywania. Wydaje mi się, że nie mam dość komfortu z dynamicznym, językowym sposobem myślenia, który sam wymyśliłem. – dsimcha
Szablony * to * metaclasses w C++, język mocno napisany. W słabo napisanym typie, takim jak Python, gdzie klasy są również obiektami, jak zauważyłeś, często nie trzeba tam iść - ale kiedy to robisz, nie jesteś ograniczony do argumentów szablonu i możesz robić niesamowite rzeczy. – martineau
** Python jest silnie wpisany **, nie można dodawać łańcucha i liczby całkowitej w Pythonie, tak jak robiłbyś to w słabo napisanym języku, takim jak Javascript. Nawiasem mówiąc, ** Python jest również wpisywany dynamicznie **. –