除了构造方法__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
在定义序列类时要注意,如果为定义某个特殊方法,但却执行了对应的操作,就会抛出异常错误。