この記事の内容は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 サイトの他の関連記事を参照してください。