8

カスタムシーケンスタイプがあります。これは基本的にリストのラッパーとブールフラグであり、通常の不変のシーケンス動作をエミュレートしたかったのです。

私の問題はスライスです。Python 3でそれを実装する方法は、が単一のインデックスである__getitem__(key)場合はアイテムを返し、がスライスオブジェクトである場合はスライスされたシーケンスを返すメソッドを持つことであることを理解しています。しかし、これらのケースをどのように区別する必要がありますか?%key%key

基本的に2つの仮説があります。

sliced_list = self.wrapped_list[key]
if isinstance(key, slice):
    return MyCustomSequenceType(sliced_list, boolean_flag)
return sliced_list

でもこれは悪ですね。または

sliced_list = self.wrapped_list[key]
try:
    return MyCustomSequenceType(sliced_list, boolean_flag)
except TypeError:
    return sliced_list

後者はよりパイソンに見えます。MyCustomSequenceType.__init__(self, datas, flag)len(datas)を呼び出すという事実に依存しているので、がであるTypeError場合%datasは発生しintegerます。しかし、その後、別のランダムな問題__init__を提起した場合、それは追跡できなくなります。TypeErrorまた、 http: //wiki.cython.org/enhancements/numpy/getitemisinstanceは、より高速な(実際にはより簡単に最適化できる)ヒントを示しています。

では、どうすればいいですか?

4

2 に答える 2

10

標準ライブラリを調べて、そこで行われていることをコピーすることができます。たとえば、calendar.pyには次のものがあります。

def __getitem__(self, i):
    funcs = self._months[i]
    if isinstance(i, slice):
        return [f(self.format) for f in funcs]
    else:
        return funcs(self.format)

これは、インデックスまたはスライスを基になるリストに渡すだけで、問題を明示的にチェックすることと、問題isinstance 部分的にダッキングすることの両方を示しています。

于 2011-05-19T10:12:38.133 に答える
2

それはisinstance(key, slice)、ではなく、である必要がありisinstance(key, "slice")ます。

__getitem__また、直接呼び出すことはできません[]。アイテム表記を使用してください。

私自身は、識別が必要な場合にこのメソッド使用します-これは非常に特殊なものであり、別のタイプに簡単に置き換えることができるものではありません(考えてみてください-が、の場合、aが返される唯一のタイプのオブジェクトです要素またはエラー以外)。isinstance(key, slice)sliceself.wrapped_listlistslice

だから私はこのようになってしまうでしょう:

sliced_list = self.wrapped_list[key]
if isinstance(key, slice):
    return MyCustomSequenceType(sliced_list, boolean_flag)
return sliced_list

スライスを特別に扱う必要があるかどうかをさらに検討してください。あなたのケースが何であるかはわかりませんが、後で物事に影響を与えるアーキテクチャ上の決定を行うときは、同じことを行ういくつかの異なる方法を検討し、それらすべてを評価して、最良のものを決定することをお勧めします(それではありません私は自分でそれをたくさんやっています-私はただ急いで、後で実装してパッチを当てる傾向があります...)。

于 2011-05-19T10:08:49.523 に答える