根据挂钩函数的返回值进行排序
names = ['Socrates', 'Archimedes', 'Plato', 'Aristotle'] names.sort(key=lambda x: len(x)) print(names)
输出
['Plato', 'Socrates', 'Aristotle', 'Archimedes']
字典 current 没有 increments 中的键时候,打印日志信息
from collections import defaultdict current = {'green': 12, 'blue': 3} increments = [ ('read', 5), ('blue', 17), ('orange', 9), ] def log_missing(): print('key added') return 0 result = defaultdict(log_missing, current) print('before: ', dict(result)) for key, amount in increments: result[key] += amount print('after: ', dict(result))
输出
before: {'green': 12, 'blue': 3} key added key added after: {'green': 12, 'blue': 20, 'read': 5, 'orange': 9}
def increment_with_report(current, increments): added_count = 0 def missing(): nonlocal added_count added_count += 1 return 0 result = defaultdict(missing, current) for key, amount in increments: result[key] += amount return result, added_count print(increment_with_report(current, increments))
输出
(defaultdict(<function increment_with_report.<locals>.missing at 0x000001EDBCB64670>, {'green': 12, 'blue': 20, 'read': 5, 'orange': 9}), 2)
缺点:把带状态的闭包函数用作挂钩有一个缺点,就是读起来比无状态的函数难懂一些。
class CountMissing: def __init__(self): self.added = 0 def missing(self): self.added += 1 return 0 counter = CountMissing() result = defaultdict(counter.missing, current) for key, amount in increments: result[key] += amount print(counter.added)
输出
2
缺点:使用辅助类来改写带状态的闭包,相对要清晰一些,但是不易理解CountMissing 对象需要由谁来构建? missing 方法由谁来调用?该类是否需要添加新的公共方法? 这些都需要看过 defaultdict 的用法后才能明白。
感觉还是难以理解
class CountMissing: def __init__(self): self.added = 0 def __call__(self, *args, **kwargs): self.added += 1 return 0 counter = CountMissing() result = defaultdict(counter, current) for key, amount in increments: result[key] += amount print(counter.added)
输出
2
__call__
方法表明 CountMissing
的类实例也会像函数那样,在合适的时候充当某个 API 使用。于是,刚读到这段代码的人就可以从这个方法开始,来理解 CountMissing
类的主要功能。 __call__
方法强烈暗示了该类的用途,它告诉我们,这个类的功能相当于一个带状态的闭包。