除了前面章节介绍的几个类特殊方法(方法名以双下划线(__)开头和结尾),在 Python 类中,我们还可以通过重写几个特殊方法,实现自定义一个序列类。表 1 列出了和自定义序列类有关的几个特殊方法。

表 1 和序列相关的特殊方法
方法名功能
__len__(self)返回序列类中存储元素的个数。
__contains__(self, value)判断当前序列中是否包含 value 这个指定元素。
__getitem__(self, key)通过指定的 key(键),返回对应的 value(值)。
__setitem__(self, key)修改指定 key(键)对应的 value(值)。
__delitem__(self, key)删除指定键值对。

注意,在对表 1 中的这些特殊方法进行重写时,在实现其基础功能的基础上,还可以根据实际情况,对各个方法的具体实现进行适当调整。以 __setitem__() 方法为例,当在序列中未找到指定 key 的情况下,该方法可以报错,当然也可以将此键值对添加到当前序列中。

另外值得一提的是,在实现自定义序列类时,并不是必须重写表 1 中全部的特殊方法。如果该自定义序列是一个不可变序列(即序列中的元素不能做修改),则无需重写 __setitem__() 和 __delitem__() 方法;反之,如果该自定义序列是一个可变序列,可以重写以上 5 个特殊方法。

下面程序实现了一个比较简单的序列类,这是一个字典类,其特点是只能存储 int 类型的元素:

class IntDic:   
    def __init__(self):
        # 用于存储数据的字典
        self.__date = {}

    def __len__(self):
        return len(list(self.__date.values()))
           
    def __getitem__(self, key):
        # 如果在self.__changed中找到已经修改后的数据
        if key in self.__date :
            return self.__date[key]
        return None
    
    def __setitem__(self, key, value):
        #判断value是否为整数
        if not isinstance(value, int):
            raise TypeError('必须是整数')
        #修改现有 key 对应的 value 值,或者直接添加
        self.__date[key] = value

    def __delitem__(self, key):
        if key in self.__date : del self.__date[key]
dic = IntDic()
#输出序列中元素的个数,调用 __len__() 方法
print(len(dic))
#向序列中添加元素,调用 __setitem__() 方法
dic['a'] = 1
dic['b'] = 2

print(len(dic))
dic['a'] = 3
dic['c'] = 4
print(dic['a'])
#删除指定元素,调用 __delitem__() 方法
del dic['a']
print(dic['a'])
print(len(dic))

程序执行结果为:

0
2
3
None
2