128

pythonはジェネリック/テンプレートタイプのシナリオをどのように処理しますか? 外部ファイル「BinaryTree.py」を作成し、バイナリツリーを処理させたいとしますが、データ型は問いません。

そのため、カスタム オブジェクトの型を渡して、そのオブジェクトのバイナリ ツリーを作成できます。これはPythonでどのように行われますか?

4

9 に答える 9

103

Pythonはダックタイピングを使用するため、複数のタイプを処理するために特別な構文は必要ありません。

TC ++のバックグラウンドをお持ちの場合は、テンプレート関数/クラスで使用される操作が(構文レベルで)あるタイプで定義されている限り、テンプレートでそのタイプを使用できることを覚えておいてTください。

したがって、基本的には同じように機能します。

  1. バイナリツリーに挿入するアイテムのタイプのコントラクトを定義します。
  2. この契約を文書化します(つまり、クラスの文書に)
  3. コントラクトで指定された操作のみを使用してバイナリツリーを実装する
  4. 楽しい

ただし、明示的な型チェックを記述しない限り(通常は推奨されません)、バイナリツリーに選択した型の要素のみが含まれるようにすることはできません。

于 2011-07-17T18:38:34.073 に答える
12

Python でジェネリック型を作成することについて良い考えを思いついた後、同じ考えを持つ他の人を探し始めましたが、見つかりませんでした。それで、ここにあります。私はこれを試してみましたが、うまくいきます。これにより、Python で型をパラメーター化できます。

class List( type ):

    def __new__(type_ref, member_type):

        class List(list):

            def append(self, member):
                if not isinstance(member, member_type):
                    raise TypeError('Attempted to append a "{0}" to a "{1}" which only takes a "{2}"'.format(
                        type(member).__name__,
                        type(self).__name__,
                        member_type.__name__ 
                    ))

                    list.append(self, member)

        return List 

このジェネリック型から型を派生させることができるようになりました。

class TestMember:
        pass

class TestList(List(TestMember)):

    def __init__(self):
        super().__init__()


test_list = TestList()
test_list.append(TestMember())
test_list.append('test') # This line will raise an exception

このソリューションは単純化されており、制限があります。ジェネリック型を作成するたびに、新しい型が作成されます。したがって、List( str )親として継承する複数のクラスは、2 つの別個のクラスから継承することになります。これを克服するには、新しい内部クラスを作成するのではなく、さまざまな形式の内部クラスを格納し、以前に作成された内部クラスを返す dict を作成する必要があります。これにより、同じパラメーターを持つ重複した型が作成されるのを防ぐことができます。興味があれば、デコレータやメタクラスを使用してより洗練されたソリューションを作成できます。

于 2016-03-28T13:32:47.497 に答える
3

Pythonは動的に型付けされるため、これは非常に簡単です。実際、どのデータ型でも機能しないようにするには、BinaryTreeクラスに追加の作業を行う必要があります。

たとえば、オブジェクトをkey()呼び出すkey()のと同じように、メソッドからオブジェクト内で使用可能なツリーにオブジェクトを配置するために使用されるキー値が必要な場合です。例えば:

class BinaryTree(object):

    def insert(self, object_to_insert):
        key = object_to_insert.key()

object_to_insertがどのようなクラスであるかを定義する必要はないことに注意してください。key()メソッドがある限り、機能します。

例外は、文字列や整数などの基本的なデータ型で機能させたい場合です。それらを一般的なBinaryTreeで機能させるには、それらをクラスでラップする必要があります。それが重すぎるように聞こえ、実際に文字列を格納するだけの効率を高めたい場合は、申し訳ありませんが、Pythonはそれが得意ではありません。

于 2011-07-17T18:36:13.377 に答える
1

組み込みのコンテナーがどのようにそれを行うかを見てください。 dictなどlistには、好きなタイプの異種要素が含まれています。たとえば、insert(val)ツリーの関数を定義すると、ある時点で次のようなことが行われnode.value = val、残りはPythonが処理します。

于 2011-07-17T18:35:22.510 に答える
1

幸いなことに、python でのジェネリック プログラミングの取り組みがいくつか行われています。ライブラリがあります:ジェネリック

これに関するドキュメントは次のとおりです。http://generic.readthedocs.org/en/latest/

何年も進歩していませんが、独自のライブラリを使用して作成する方法の大まかなアイデアを得ることができます。

乾杯

于 2014-10-25T06:02:27.437 に答える