File: LP6E/Chapter39/decorator_state_globals.py

calls = 0
def tracer(func):                         # State via enclosing scope and global
    def wrapper(*args, **kwargs):         # Instead of class attributes
        global calls                      # calls is global, not per-function
        calls += 1
        print(f'call {calls} to {func.__name__}')
        return func(*args, **kwargs)
    return wrapper

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

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

if __name__ == '__main__':
    hack(1, 2, 3)            # Really calls wrapper, assigned to hack
    hack(a=4, b=5, c=6)      # wrapper calls hack

    code(4, 2)               # Really calls wrapper, assigned to code
    code(2, y=16)            # Global calls is not per-decoration here!



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