about 3 years ago

Accept Functions for Simple Interfaces Instead of Classes

defaultdict 的第一個引數是 function ,例如下面的程式計算兩個 dictionaries 差了多少個 key

def increment_with_report(current, increments):
    added_count = 0

    def missing():
        nonlocal added_count  # Stateful closure

        added_count += 1
        return 0

    result = defaultdict(missing, current)
    for key, amount in increments:
        result[key] += amount

    return result, added_count


current = {'green': 12, 'blue': 3}
increments = [
    ('red', 5),
    ('blue', 17),
    ('orange', 9),
]
result, count = increment_with_report(current, increments)
assert count == 2

但是使用 closure 造成可讀性下降,比較好的方式是使用 callable class 來處理

class BetterCountMissing(object):
    def __init__(self):
        self.added = 0

    def __call__(self):
        self.added += 1
        return 0

counter = BetterCountMissing()
result = defaultdict(counter, current)

相關

Python 慣用語 - 22 defaultdict

← Effective Python 心得筆記: Item 22 Effective Python 心得筆記: Item 24 →
 
comments powered by Disqus