File: LP6E/Chapter39/decorator_state_classes.py

class tracer:                                # State via instance attributes
    def __init__(self, func):                # On @ decorator
        self.calls = 0                       # Save func for later call
        self.func  = func
    def __call__(self, *args, **kwargs):     # On call to original function
        self.calls += 1
        print(f'call {self.calls} to {self.func.__name__}')
        return self.func(*args, **kwargs)

@tracer
def hack(a, b, c):           # Same as: hack = tracer(hack)
    print(a + b + c)         # Triggers tracer.__init__

@tracer
def code(x, y):              # Same as: code = tracer(code)
    print(x ** y)            # Wraps code in a tracer object

if __name__ == '__main__':
    hack(1, 2, 3)            # Really calls tracer instance: runs tracer.__call__
    hack(a=4, b=5, c=6)      # hack is an instance attribute

    code(4, 2)               # Really calls tracer instance: self.func is code
    code(2, y=16)            # self.calls is per-decoration here



[Home page] Books Code Blog Python Author Train Find ©M.Lutz