シーケンスのマジックメソッド

PythonBeginner
オンラインで実践に進む

はじめに

このチュートリアルでは、Python のシーケンスマジックメソッドについて説明します。これらのメソッドを使うと、オブジェクトの長さを取得したり、アイテムにアクセスしたり、スライスしたり、反復処理したりなど、さまざまな操作で独自のクラスの動作をカスタマイズできます。

長さと含まれる要素

長さと含まれる要素のメソッドは、Python の特殊メソッドで、len()innot in などの組み込み関数や演算子と共に使用される場合のオブジェクトの動作を定義します。

まずは簡単なオブジェクトから始めましょう。sequence.py で、属性 data を持つ MySequence という名前のクラスを作成します。

class MySequence:
    def __init__(self, data: list):
        """Initialize a new MySequence object with the given data."""
        self.data = data

__len__

__len__ マジックメソッドは、クラスのインスタンスに対して len() 関数を適用した場合の動作を定義するために使用されます。

    #... (sequence.py の前のコード)

    def __len__(self) -> int:
        """Return the length of the sequence."""
        return len(self.data)

__contains__

__contains__ マジックメソッドは、クラスのインスタンスに対して in 演算子と not in 演算子を適用した場合の動作を定義するために使用されます。

    #... (sequence.py の前のコード)

    def __contains__(self, item: object) -> bool:
        """Check if the sequence contains the given item."""
        return item in self.data

例:長さと含まれる要素のメソッドの使用

これで MySequence クラスの長さと含まれる要素のメソッドを定義したので、length_containment_example.py でそれらがどのように機能するか見てみましょう。

from sequence import MySequence

## Create a MySequence object
my_seq = MySequence([1, 2, 3, 4, 5])

## Test the __len__ magic method
print(len(my_seq))  ## Output: 5

## Test the __contains__ magic method
print(3 in my_seq)  ## Output: True
print(3 not in my_seq)  ## Output: False
print(10 in my_seq)  ## Output: False

次に、ターミナルで以下のコマンドを入力してスクリプトを実行します。

python length_containment_example.py

アイテムへのアクセス

アイテムへのアクセスメソッドは、Python の特殊メソッドで、角括弧表記 [] を使ってアクセスした場合のオブジェクトの動作を定義します。

__getitem__

__getitem__ マジックメソッドは、クラスのインスタンス内のアイテムにアクセスするための角括弧表記の動作を定義するために使用されます。

    #... (sequence.py の前のコード)

    def __getitem__(self, index: int) -> object:
        """Return the item at the given index."""
        return self.data[index]

__setitem__

__setitem__ マジックメソッドは、クラスのインスタンス内のアイテムを設定するための角括弧表記の動作を定義するために使用されます。

    #... (sequence.py の前のコード)

    def __setitem__(self, index: int, value: object) -> None:
        """Set the item at the given index to the given value."""
        self.data[index] = value

__delitem__

__delitem__ マジックメソッドは、クラスのインスタンスに対して del キーワードを適用した場合の動作を定義するために使用されます。

    #... (sequence.py の前のコード)

    def __delitem__(self, index: int) -> None:
        """Remove the item at the given index."""
        del self.data[index]

例:アイテムへのアクセスメソッドの使用

これで MySequence クラスのアイテムへのアクセスメソッドを定義したので、item_access_example.py でそれらがどのように機能するか見てみましょう。

from sequence import MySequence

## Create a MySequence object
my_seq = MySequence([1, 2, 3, 4, 5])

## Test the __getitem__ magic method
print(my_seq[2])  ## Output: 3

## Test the __setitem__ magic method
my_seq[2] = 9
print(my_seq[2])  ## Output: 9

## Test the __delitem__ magic method
del my_seq[2]
print(len(my_seq))  ## Output: 4
print(my_seq.data)  ## Output: [1, 2, 4, 5]

次に、ターミナルで以下のコマンドを入力してスクリプトを実行します。

python item_access_example.py

反復処理

反復処理メソッドは、Python の特殊メソッドで、反復処理プロトコルと共に使用される場合のオブジェクトの動作を定義します。

__iter__

__iter__ マジックメソッドは、iter() 関数と for... in... ループの動作を、クラスのインスタンスに対して適用した場合に定義するために使用されます。

    #... (sequence.py の前のコード)

    def __iter__(self):
        """Return an iterator for the sequence."""
        for item in self.data:
            yield item

__reversed__

__reversed__ マジックメソッドは、reversed() 関数の動作を、クラスのインスタンスに対して適用した場合に定義するために使用されます。

    #... (sequence.py の前のコード)

    def __reversed__(self):
        """Return a reversed iterator for the sequence."""
        return reversed(self.data)

例:反復処理メソッドの使用

これで MySequence クラスの反復処理メソッドを定義したので、iteration_example.py でそれらがどのように機能するか見てみましょう。

from sequence import MySequence

## Create a MySequence object
my_seq = MySequence([1, 2, 3, 4, 5])

## Test the __iter__ magic method
for item in my_seq:
    print(item, end=" ")  ## 出力:1 2 4 5

## Test the __reversed__ magic method
for item in reversed(my_seq):
    print(item, end=" ")  ## 出力:5 4 2 1

次に、ターミナルで以下のコマンドを入力してスクリプトを実行します。

python iteration_example.py

まとめ

実装したマジックメソッドにより、自作の MySequence クラスは現在、リストやタプルなどの組み込みシーケンス型と同じように動作します。これで、Python のネイティブなシーケンスと同じように使うことができます。