4

私はこのようなことをしたい:

class Dictable:
    def dict(self):
        raise NotImplementedError

class Foo(Dictable):
    def dict(self):
        return {'bar1': self.bar1, 'bar2': self.bar2}

これを行うためのよりPythonicな方法はありますか? たとえば、組み込みの変換をオーバーロードすることは可能dict(...)ですか? 必ずしもすべてのメンバー変数を返したいわけではないことに注意してくださいFoo。むしろ、各クラスに何を返すかを決定させたいと思います。

ありがとう。

4

4 に答える 4

5

Pythonic の方法は、何をしたいかによって異なります。オブジェクトがそれ自体でマッピングと見なされるべきではない場合、メソッドはまったく問題ありませんが、 dictable を処理するためにdict「オーバーロード」するべきではありません。dict基本クラスが必要かどうかは、実行するかどうかによって異なりますisinstance(x, Dictable)hasattr(x, "dict")ほぼ同じ目的に役立つことに注意してください。

クラス概念的にキーから値へのマッピングである場合、Mappingプロトコルの実装は適切と思われます。つまり、実装します

  • __getitem__
  • __iter__
  • __len__

から継承しcollections.Mappingて、他のメソッドを取得します。その後dict(Foo())、無料で入手できます。例:

class Foo(Mapping):
    def __getitem__(self, key):
        if key not in ("bar1", "bar2"):
            raise KeyError("{} not found".format(repr(key))
        return getattr(self, key)

    def __iter__(self):
        yield "bar1"
        yield "bar2"

    def __len__(self):
        return 2
于 2012-06-24T22:33:35.690 に答える
1

まず、collections.ABCPython 抽象基本クラス プロトコル (静的言語のインターフェイスに相当) について説明している を見てください。

次に、独自の ABC を作成するか、既存の ABC を利用するかを決定します。この場合、Mappingが必要な場合があります。

dictコンストラクター (つまりdict(my_object)) はオーバーライド可能ではありませんが、キーと値のペアのシーケンスを生成する反復可能なオブジェクトに遭遇した場合、それから dict を構築することに注意してください。つまり (Python 2; Python 3 の場合は に置き換えますitems) iteritems:

def __iter__(self):
    return {'bar1': self.bar1, 'bar2': self.bar2}.iteritems()

ただし、クラスが のように動作することを意図している場合は、これを行うべきではありません。これは、キーと値のペアではなく、キーを反復処理するdictというインスタンスの予期される動作とは異なるためです。Mapping特に、for .. in不適切な動作を引き起こす可能性があります。

于 2012-06-24T22:42:54.093 に答える
0

ここでの回答のほとんどは、クラスを dict のように動作させることに関するものであり、実際にはあなたが尋ねたものではありません。「私は dict に変換できるクラスです」という考えを表現したい場合は、単純に一連のクラスを定義し、それぞれに .dict() を実装させます。Python は、オブジェクトそのものよりもダックタイピング (オブジェクトができること) を優先します。ABC はあまり追加しません。ドキュメントも同じ目的を果たします。

于 2012-06-24T22:54:14.643 に答える
0

確かに dict() をオーバーロードできますが、ほとんどしたくありません! 標準ライブラリの多くの側面は、利用可能な dict に依存しており、その機能のほとんどを壊してしまいます。ただし、おそらく次のようなことを行うことができます。

class Dictable:
   def dict(self):
     return self.__dict__
于 2012-06-24T22:29:58.773 に答える