python decorators

def identity(x):
    return x
def trace(func):
    def inner(*args, **kwargs):
        print(
            f'{func.__name__} called '
            f'with {args}, {kwargs}'
        )
        return func(*args, **kwargs)
    return inner
def identity(x):
    return x
  
def trace(func):
    def inner(*args, **kwargs):
        ...
        return func(*args, **kwargs)
    return inner
identity.__name__
# identity

identity = trace(identity)
identity.__name__
# inner
def identity(x):
    return x
  
def trace(func):
    def inner(*args, **kwargs):
        ...
        return func(*args, **kwargs)
    return inner
identity(1)
# 1

identity = trace(identity)
identity(1)
# identity called with (1,), {}
# 1
def trace(func):
    def inner(*args, **kwargs):
        ...
        return func(*args, **kwargs)
    return inner
def identity(x):
    return x

identity = trace(identity)
@trace
def identity(x):
    return x
def identity(x):
    return x

def inc(x):
    return x + 1
  
def trace(func):
    def inner(*args, **kwargs):
        ...
        return func(*args, **kwargs)
    return inner
identity = trace(identity)
identity
# <function trace.<locals>.inner at 0x7fb3afc6cee0>

inc = trace(inc)
inc
# <function trace.<locals>.inner at 0x7fb3afc6cf70>
def identity(x):
    """ I do nothing useful. """
    return x

def trace(func):
    def inner(*args, **kwargs):
        ...
        return func(*args, **kwargs)
    
    inner.__name__ = func.__name__
    return inner
identity = trace(identity)
identity.__name__
# identity
identity.__doc__
# None
from functools import update_wrapper

def identity(x):
    """ I do nothing useful. """
    return x

def trace(func):
    def inner(*args, **kwargs):
        ...
        return func(*args, **kwargs)
    
    inner = update_wrapper(inner, func)
    return inner
identity = trace(identity)
identity.__name__
# identity
identity.__doc__
# I do nothing useful. 
from functools import wraps

def identity(x):
    """ I do nothing useful. """
    return x

def trace(func):
    @wraps(func)
    def inner(*args, **kwargs):
        ...
        return func(*args, **kwargs)
    
    return inner
identity = trace(identity)
identity.__name__
# identity
identity.__doc__
# I do nothing useful. 
from functools import wraps

def double(func):
    @wraps(func)
    def inner(*args, **kwargs):
        return func(*args, **kwargs) * 2

    return inner

def add_42(func):
    @wraps(func)
    def inner(*args, **kwargs):
        return func(*args, **kwargs) + 42

    return inner
@double
@add_42
def identity(x):
    return x
@add_42
@double
def identity(x):
    return x
identity(3)
# 90

# (3 + 42) * 2
identity(3)
# 48

# (3 * 2) + 42
@double
@add_42
def identity(x):
    return x
def func(x):
    return x

func = deco(func)
@deco
def func(x):
    return x
identity = double(
    add_42(identity)
)
identity = add_42(identity)
identity = double(identity)
def trace_stdout(func):
    @wraps(func)
    def inner(*args, **kwargs):
        print(
            f'{func.__name__} called',
            file=sys.stdout,
        )
        return func(*args, **kwargs)
    return inner
def trace_stderr(func):
    @wraps(func)
    def inner(*args, **kwargs):
        print(
            f'{func.__name__} called',
            file=sys.stderr,
        )
        return func(*args, **kwargs)
    return inner
deco = trace(param)
@trace(param)
def func(x):
    return x
@deco
def func(x):
    return x
deco = trace(param)
def func(x):
    return x

func = deco(func)
def deco(func):
    @wraps(func)
    def inner(*args, **kwargs):
        print(f'{func.__name__} called')
        return func(*args, **kwargs)
    return inner
def trace(output):
    def deco(func):
        @wraps(func)
        def inner(*args, **kwargs):
            print(
                f'called {func.__name__}',
                file=output,
            )
            return func(*args, **kwargs)
        return inner
    return deco
def trace(output):
    def deco(func):
        @wraps(func)
        def inner(*args, **kwargs):
            print(
                f'called {func.__name__}',
                file=output,
            )
            return func(*args, **kwargs)
        return inner
    return deco
@trace(sys.stdout)
def identity(x):
    return x

@trace(sys.stderr)
def inc(x):
    return x + 1
def trace(func):
    called = 0

    @wraps(func)
    def inner(*args, **kwargs):
        nonlocal called
        called += 1
        print(
            f'{func.__name__} called at '
            f'{called} time'
        )
        return func(*args, **kwargs)
    return inner
@trace
def identity(x):
    return x
identity(42)
# identity called at 1 time
identity(42)
# identity called at 2 time
def trace(func):
    @wraps(func)
    def inner(*args, **kwargs):
        inner.times_called += 1
        return func(*args, **kwargs)

    inner.times_called = 0
    return inner
@trace
def identity(x):
    return x
identity(42)
identity(42)
identity.times_called
# 2
class A:
    def __init__(self, x):
        self._x = x
        
    @property
    def x(self):
        return self._x
    
    @x.setter
    def x(self, value):
        if value <= 0:
            raise ValueError(
              "positive value expected"
            )
        self._x = value
a = A(42)
print(a.x)
a.x = 100
class Complex:
    def __init__(self, real, imaginary):
        self._real = real
        self._imaginary = imaginary
        
    @classmethod
    def from_int(cls, value):
        return cls(real=value, imaginary=0)
c1 = Complex(1, 2)
# 1 + i 2

c2 = Complex.from_int(14)
# 14 + i 0
from functools import singledispatch


@singledispatch
def pack(value):
    raise ValueError(f'{value} is not supported')

@pack.register
def deserialize_int(value: int):
    return b'I' + hex(value).encode('ascii')

@pack.register
def deserialize_list(value: list):
    return b'L' + b','.join(pack(v) for v in value)
pack(1)
# b'I0x1'
pack([1, 2, 3])
# b'LI0x1,I0x2,I0x3'

pack(3.14)
# ValueError: 3.14 is not supported

07 python decorators

By persi

07 python decorators

  • 144