序列魔法方法

PythonBeginner
立即练习

介绍

在本教程中,我们将介绍 Python 中的序列魔法方法(sequence magic methods)。这些方法允许你在不同的操作中自定义类的行为,例如获取对象的长度、访问元素、切片和迭代。

长度与包含

长度和包含方法是 Python 中的特殊方法,它们允许对象在使用内置函数或操作符(如 len()innot in)时定义其行为。

让我们从一个简单的对象开始。在 sequence.py 中,创建一个名为 MySequence 的类,该类具有一个属性 data

class MySequence:
    def __init__(self, data: list):
        """初始化一个新的 MySequence 对象,并传入给定的数据。"""
        self.data = data

__len__

__len__ 魔法方法用于定义 len() 函数在应用于类的实例时的行为。

    ## ... (sequence.py 中的先前代码)

    def __len__(self) -> int:
        """返回序列的长度。"""
        return len(self.data)

__contains__

__contains__ 魔法方法用于定义 innot in 操作符在应用于类的实例时的行为。

    ## ... (sequence.py 中的先前代码)

    def __contains__(self, item: object) -> bool:
        """检查序列是否包含给定的项。"""
        return item in self.data

示例:使用长度与包含方法

现在我们已经为 MySequence 类定义了长度和包含方法,让我们看看它们在 length_containment_example.py 中是如何工作的:

from sequence import MySequence

## 创建一个 MySequence 对象
my_seq = MySequence([1, 2, 3, 4, 5])

## 测试 __len__ 魔法方法
print(len(my_seq))  ## 输出:5

## 测试 __contains__ 魔法方法
print(3 in my_seq)  ## 输出:True
print(3 not in my_seq)  ## 输出:False
print(10 in my_seq)  ## 输出:False

然后在终端中输入以下命令来执行脚本。

python length_containment_example.py

元素访问

元素访问方法是 Python 中的特殊方法,它们允许对象在使用方括号符号 [] 访问时定义其行为。

__getitem__

__getitem__ 魔法方法用于定义方括号符号在访问类的实例中的元素时的行为。

    ## ... (sequence.py 中的先前代码)

    def __getitem__(self, index: int) -> object:
        """返回给定索引处的元素。"""
        return self.data[index]

__setitem__

__setitem__ 魔法方法用于定义方括号符号在设置类的实例中的元素时的行为。

    ## ... (sequence.py 中的先前代码)

    def __setitem__(self, index: int, value: object) -> None:
        """将给定索引处的元素设置为给定的值。"""
        self.data[index] = value

__delitem__

__delitem__ 魔法方法用于定义 del 关键字在应用于类的实例时的行为。

    ## ... (sequence.py 中的先前代码)

    def __delitem__(self, index: int) -> None:
        """移除给定索引处的元素。"""
        del self.data[index]

示例:使用元素访问方法

现在我们已经为 MySequence 类定义了元素访问方法,让我们看看它们在 item_access_example.py 中是如何工作的:

from sequence import MySequence

## 创建一个 MySequence 对象
my_seq = MySequence([1, 2, 3, 4, 5])

## 测试 __getitem__ 魔法方法
print(my_seq[2])  ## 输出:3

## 测试 __setitem__ 魔法方法
my_seq[2] = 9
print(my_seq[2])  ## 输出:9

## 测试 __delitem__ 魔法方法
del my_seq[2]
print(len(my_seq))  ## 输出:4
print(my_seq.data)  ## 输出:[1, 2, 4, 5]

然后在终端中输入以下命令来执行脚本。

python item_access_example.py

迭代

迭代方法是 Python 中的特殊方法,它们允许对象在使用迭代协议时定义其行为。

__iter__

__iter__ 魔法方法用于定义 iter() 函数和 for ... in ... 循环在应用于类的实例时的行为。

    ## ... (sequence.py 中的先前代码)

    def __iter__(self):
        """返回序列的迭代器。"""
        for item in self.data:
            yield item

__reversed__

__reversed__ 魔法方法用于定义 reversed() 函数在应用于类的实例时的行为。

    ## ... (sequence.py 中的先前代码)

    def __reversed__(self):
        """返回序列的反向迭代器。"""
        return reversed(self.data)

示例:使用迭代方法

现在我们已经为 MySequence 类定义了迭代方法,让我们看看它们在 iteration_example.py 中是如何工作的:

from sequence import MySequence

## 创建一个 MySequence 对象
my_seq = MySequence([1, 2, 3, 4, 5])

## 测试 __iter__ 魔法方法
for item in my_seq:
    print(item, end=" ")  ## 输出:1 2 4 5

## 测试 __reversed__ 魔法方法
for item in reversed(my_seq):
    print(item, end=" ")  ## 输出:5 4 2 1

然后在终端中输入以下命令来执行脚本。

python iteration_example.py

总结

通过实现这些魔法方法,我们的自定义 MySequence 类现在表现得类似于内置的序列类型(如列表和元组)。你现在可以像使用原生 Python 序列一样使用它。