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