『Effective Python』の続き。Callableなクラスも。 www.effectivepython.com
list
のsort
メソッドやcollections.defaultdict
のdefault_factory
に渡すような函数についての話。
他の言語だとフックを実現するには抽象クラスを定義する必要があるけど、Pythonなら函数を定義すればよい、という話だが他の言語をよくしらないのでこのありがたみがよくわからないのが難点である。
また、クロージャを使えば、ステートフルな函数も定義できてフックとして使えるけれども、読みづらくなるから__call__
を実装したクラスを使おう、という提案である。
以下は、collections.defaultdict
のdefault_factory
として「存在しないキーにアクセスした回数をカウントするcallableなクラス」を渡している例である。Betterとなっているのは__call__
ではなくmissing
というメソッドを持ったクラスを説明のために定義しているからである。
from collections import defaultdict class BetterCountMissing(object): def __init__(self): self.added = 0 def __call__(self): self.added += 1 return 0 current = {'green': 12, 'blue': 3} increments = [ ('red', 5), ('blue', 17), ('orange', 9), ] counter = BetterCountMissing() result = defaultdict(counter, current) for key, amount in increments: result[key] += amount assert counter.added == 2
3章になると、1つの項目が長くなるので読むのが大変である。仕事場ではPythonは虐げられた存在だから勤務時間外で細々と読むほか無いのである。