何かを書き留める何か

数学や読んだ本について書く何かです。最近は社会人として生き残りの術を学ぶ日々です。

『Effective Python』Item 23: 単純なインタフェースではクラスの代わりに関数を受けよう

『Effective Python』の続き。Callableなクラスも。 www.effectivepython.com

listsortメソッドcollections.defaultdictdefault_factoryに渡すような函数についての話。 他の言語だとフックを実現するには抽象クラスを定義する必要があるけど、Pythonなら函数を定義すればよい、という話だが他の言語をよくしらないのでこのありがたみがよくわからないのが難点である。

また、クロージャを使えば、ステートフルな函数も定義できてフックとして使えるけれども、読みづらくなるから__call__を実装したクラスを使おう、という提案である。 以下は、collections.defaultdictdefault_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は虐げられた存在だから勤務時間外で細々と読むほか無いのである。