Item 35: getitem, setitem, and contains

from collections import defaultdict

class PrintDict(defaultdict):
    def __getitem__(self, key):
        print('getitem:', 'before:', key)
        value = super().__getitem__(key)
        print('getitem:', 'after:', key, value)
        return value
    def __contains__(self, key):
        print('contains:', 'before:', key)
        value = super().__contains__(key)
        print('contains:', 'after:', key, value)
        return value
    def __setitem__(self, key, value):
        print('setitem:', 'before:', key, value)
        super().__setitem__(key, value)
        print('setitem:', 'after:', key, value)

def show(x, func):
    print(x, '----'); print(x, func()); print(x, '====')

x = PrintDict(int)
x[1] = 5; show('A', lambda: x[1])
x[1] = 6; show('B', lambda: x[1])
x[2] += 7; show('C', lambda: x[2])
x[2] += 8; show('D', lambda: x[2])
show('E', lambda: x[3])
show('F', lambda: 4 in x)