用户定义的可调用类型
用户定义的可调用类型
不仅Python函数是真正的对象,任何Python对象都可以表现得像函数。为此,只需要实现方法__call__
# 调用BingoCage实例,从打乱的列表中取出一个元素
import random
class BingoCage:
def __init__(self, items):
self._items = list(items) # __init__接受任何可迭代对象:在本地构建一个副本,防止列表参数的意外副作用
random.shuffle(self._items) # 使用shuffle函数打乱列表self._items
def pick(self): # 随机取出列表中的数
try:
return self._items.pop() #
except IndexError:
raise LookupError('pick from empty BingoCage') # 如果列表为空,抛出异常,并设置错误信息
def __call__(self): # bingo.pick()的快捷方式是bingo()
return self.pick()
bingo=BingoCage(range(3))
bingo.pick()
0
bingo()
2
callable(bingo)
True
实现__call__方法的类是创建函数类对象的简便方式,此时必须在内部维护一个状态,让它在调用之间可用,例如BingoCage中的剩余元素。装饰器就是这样。装饰器必须是函数,而且有时要在多次调用之间“记住”某些事(例如备忘(memorization),即缓存消耗较大的计算结果,供后面使用)。
创建保有内部状态的函数,还有一种截然不同的方式——使用闭包。