Python进阶之路 自定义序列

自定义序列

除了构造方法__init__,还可以使用如下4个特殊方法定义自己的序列类,就像以前说过的列表、字典等序列一样,只不过拥有自己特殊的行为。所有的特殊方法在名称前后都需要双下划线__

  • __len__(self):返回序列中元素的个数。使用len函数获取序列对象的长度时会调用该方法。
  • __getitem__(self,key):返回与所给键对应的值。__getitem__方法的第2个参数表示键(key)。在使用sequence[key]获取值时会调用该方法。
  • __setitem__(self,key,value):设置key对应的值。__setitem__方法的第2个参数表示键(key),第3个参数不表示值(value)。当使用sequence[key] = value设置序列中键对应的值时调用该方法。
  • __delitem__(self,key):从序列中删除键为key的key-value对。当使用del关键字删除序列中键为key的key-value对时调用该方法。

从这4个方法的描述来看,都是对序列的某些操作触发了这些特殊方法的调用。

[例 10.4] 本例定义了一个名为FactorialDict的序列类,该类的功能是计算key对应的value的阶乘,也就是说,在赋值时需要为某个key设置一个整数或可以转换为整数的值,但在使用该key获取对应的value时,返回的确实value的阶乘。

class FactoriaDict:
    def __init__(self):
        # 创建字典对象
        self.numDict = {}
    # 用于计算阶乘的方法
    def factorial(self,n):
        if n == 0 or n == 1:
            return 1
        else:
            return n * self.factorial(n -1)

    # 从字典中获取key对应的value时调用该方法
    def __getitem__(self,key):
        print('__getitem__方法被调用,key={}'.format(key))
        # 判断key是否在字典中存在,如果存在,返回value的阶乘,否则返回0
        if key in self.numDict:
            return self.factorial(self.numDict[key])
        else:
            return 0

    # 设置key对应的value时调用该方法
    def __setitem__(self,key,value):
        print('__setitem__方法被调用,key={}'.format(key))
        self.numDict[key] = int(value)

    # 使用del语句删除key对应的key-value对时调用
    def __delitem__(self, key):
        print('__delitem__方法被调用,key={}'.format(key))
        del self.numDict[key]

    # 使用len函数获取字典中key-value对个数时调用
    def __len__(self):
        print('__len__方法被调用')
        return len(self.numDict)

# 创建FactorialDict对象
d = FactoriaDict()
# 设置字典中的key-value值对
d['4!'] = 4
d['7!'] = 7
d['12!'] = 12
# 获取4的阶乘
print('4!', '=', d['4!'])
# 获取7的阶乘
print('7!', '=', d['7!'])
# 获取12的阶乘
print('12!', '=', d['12!'])
# 获取字典的长度
print('len', '=', len(d))
# 删除key为'7!'的key-value对
del d['7!']
# 获取7的阶乘
print('7!', '=', d['7!'])
# 获取字典的长度
print('len', '=', len(d))

输出结果:

__setitem__方法被调用,key=4!
__setitem__方法被调用,key=7!
__setitem__方法被调用,key=12!
__getitem__方法被调用,key=4!
4! = 24
__getitem__方法被调用,key=7!
7! = 5040
__getitem__方法被调用,key=12!
12! = 479001600
__len__方法被调用
len = 3
__delitem__方法被调用,key=7!
__getitem__方法被调用,key=7!
7! = 0
__len__方法被调用
len = 2

在定义序列类时要注意,如果为定义某个特殊方法,但却执行了对应的操作,就会抛出异常错误。

你可能感兴趣的:(Python,Python进阶之路)