6

Pythonメタクラスに関するチュートリアルをいくつか読みました。これまで使用したことはありませんが、比較的単純なものに1つ必要であり、すべてのチュートリアルははるかに複雑なユースケースを対象としているようです。基本的に、事前に指定された本体を持つテンプレートクラスを作成したいのですが、その基本クラスをパラメーターとして受け取ります。C ++ / Dテンプレートからアイデアを得たので、C++で記述したいコードの例を次に示します。

template<class T>
    class Foo : T {
        void fun() {}
    }
4

2 に答える 2

10

確かにメタクラスを使用して実行できますが、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の洞察 (現在は削除されたコメント) に触発されたものです。

于 2010-10-06T21:43:04.817 に答える
0

Python ではテンプレートがないため、これは意味がありません。C++ のパラメーター化されたテンプレートについての私の理解 (私がそれらを見てから何年も経っているので、かなり曖昧です) は、それがクラス ファクトリのように機能し、追加のメソッドを持つ任意のクラスのサブクラスを作成できるということです。または属性が追加されました。

Python では、クラスを受け取り、実行時に新しいクラスを返すファクトリ関数を使用してこれを行うことができます。

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
于 2010-10-06T21:48:53.240 に答える