確かにメタクラスを使用して実行できますが、Python ではクラス自体がオブジェクトであるため、メタクラスがなくてもやりたいことを実行できます。つまり、驚くべきことに、C++ コードをほぼ 1 対 1 で変換するだけで済みます。このため、比較的単純であることに加えて、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()
出力:
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()
(想像を絶する名前の) 関数内のコードは、一般にクラス ファクトリまたはFactory パターンの実装template()
と呼ばれるものの例です。ちなみに、「クラス ファクトリとは正確には何ですか?」という質問に対する私の答えが見つかるかもしれません。有益な。
編集:返されたサブクラスごとに異なるクラス名を作成するコードを追加しました。これは、製造されたクラスが常に同じ名前である場合にデバッグ時に混乱が生じる可能性についての@ aaronasterlingの洞察 (現在は削除されたコメント) に触発されたものです。