スライス機能を実装するための Python カスタム オブジェクトの紹介 (コード例)

不言
リリース: 2018-12-30 10:40:50
転載
2759 人が閲覧しました

この記事の内容はPythonカスタムオブジェクトのスライス機能の紹介(コード例)ですので、ある程度の参考価値はありますので、困っている方は参考にしていただければ幸いです。

1. マジック メソッド: __getitem__()

カスタム オブジェクトにスライス構文をサポートさせるのは難しくありません。定義するときに指定するだけで済みます。このクラスは、マジック メソッド __getitem__() を実装します。ということで、まずはこの方法を紹介していきます。

構文: object.__getitem__(self, key)

公式ドキュメント定義: 呼び出されます self[key] の評価を実装します。シーケンス型の場合、受け入れられる キーは整数であり、オブジェクトをスライスする必要があります。 負のインデックスの解釈 (クラスが シーケンス型) は __getitem__() メソッドに依存します。 不適切な型の場合は、TypeError が発生する可能性があります。 シーケンスのインデックスのセットの外側 (特別な処理の後) 負の値の解釈)、IndexError が発生する必要があります。 マッピング タイプ、キーが見つからない (コンテナー内にない) 場合、KeyError は次のようになります。

要約翻訳: __getitem__() メソッドはパラメータ キーを返すために使用されます。 対応する値、このキーは整数値またはスライス オブジェクトにすることができ、負のインデックスをサポートします。キーが上記の 2 つのタイプでない場合は、 TypeError; インデックスが範囲外の場合は IndexError がスローされます; マッピング タイプが定義されている場合、キー パラメータがそのオブジェクトのキー値ではない場合はスローされます キーエラー。

2. シーケンスをカスタマイズしてスライス関数を実装する

次に、単純な MyList を定義し、それにスライス関数を追加します。 (PS: デモのみのため、他の機能の完全性は保証されません)。

class MyList():
    def __init__(self):
        self.data = []
    def append(self, item):
        self.data.append(item)
    def __getitem__(self, key):
        print("key is : " + str(key))
        return self.data[key]

l = MyList()
l.append("My")
l.append("name")
l.append("is")
l.append("Python猫")

print(l[3])
print(l[:2])
print(l['hi'])

### 输出结果:
key is : 3
Python猫
key is : slice(None, 2, None)
['My', 'name']
key is : hi
Traceback (most recent call last):
...
TypeError: list indices must be integers or slices, not str
ログイン後にコピー

出力結果から判断すると、カスタマイズされた MyList はインデックスによる検索とスライス操作の両方をサポートしており、これはまさに私たちの目的です。

特別な注意は、この例では __getitem__() であることです。 このメソッドは、パラメーターの種類に応じてさまざまな関数 (インデックス ビット値またはスライス値の取得) を実装し、例外も適切に処理するため、面倒な処理ロジックを記述する必要はありません。インターネット上には完全に誤解を招く学習教材がたくさんあります。それらは、さまざまなタイプのパラメータを区別する方法を教え、その後、インデックス検索とスライス構文を実装するための大きなコードを記述します。それはまったく余分です。代表的なエラー例を次に示します:

###略去其它代码####
def __getitem__(self, index):
    cls = type(self)
    if isinstance(index, slice):  # 如果index是个切片类型,则构造新实例
       return cls(self._components[index])
    elif isinstance(index, numbers.Integral):  # 如果index是个数,则直接返回
        return self._components[index]
    else:
        msg = "{cls.__name__} indices must be integers"
        raise TypeError(msg.format(cls=cls))
ログイン後にコピー

3. スライス機能を実装するためのカスタム辞書

スライスはシーケンス型の機能であるため、上記の例では、スライスの具体的な実装ロジックを記述する必要はありません。ただし、その他の非シーケンス タイプのカスタム オブジェクトの場合は、スライス ロジックを自分で実装する必要があります。例としてカスタム辞書を取り上げます (追記: これはデモンストレーションのみを目的としており、他の関数の完全性は保証されていません):

class MyDict():
    def __init__(self):
        self.data = {}
    def __len__(self):
        return len(self.data)
    def append(self, item):
        self.data[len(self)] = item
    def __getitem__(self, key):
        if isinstance(key, int):
            return self.data[key]
        if isinstance(key, slice):
            slicedkeys = list(self.data.keys())[key]
            return {k: self.data[k] for k in slicedkeys}
        else:
            raise TypeError

d = MyDict()
d.append("My")
d.append("name")
d.append("is")
d.append("Python猫")
print(d[2])
print(d[:2])
print(d[-4:-2])
print(d['hi'])

### 输出结果:
is
{0: 'My', 1: 'name'}
{0: 'My', 1: 'name'}
Traceback (most recent call last):
...
TypeError
ログイン後にコピー

上記の例の重要な点は、キー値を取り出すことです。辞書のスライスとキー値のリストのスライス処理の利点は、インデックスの範囲外や負のインデックスを気にする必要がなく、辞書のスライスが辞書のスライスに変換されることです。主要な値を設定し、最終的に目標を達成します。

4. 概要

最終概要: この記事では、__getitem__() マジック メソッドを紹介し、カスタム オブジェクトの実装に使用されます (例としてリスト タイプと辞書タイプを取り上げます)。のスライス機能、お役に立てば幸いです。

以上がスライス機能を実装するための Python カスタム オブジェクトの紹介 (コード例)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
ソース:segmentfault.com
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート