Skip to content

Instantly share code, notes, and snippets.

@matklad
Created September 28, 2018 18:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save matklad/9ab00a4d60e91d6c1e7b49dac5623f85 to your computer and use it in GitHub Desktop.
Save matklad/9ab00a4d60e91d6c1e7b49dac5623f85 to your computer and use it in GitHub Desktop.
decorators.py
def max(*args):
"""Finds the largest argument."""
print(f"max{args} = ...")
ret = 0
for x in args:
ret = ret if x < ret else x
print(f"max{args} = {ret}")
return ret
def foo():
max(-10, -1, -3)
foo()
def trace(f):
def inner(*args, **kwargs):
call = ", ".join(
[str(a) for a in args] + [f"{k}={v}" for k, v in kwargs]
)
print(f"{f.__name__}({call}) = ...")
ret = f(*args, **kwargs)
print(f"{f.__name__}({call}) = {ret}")
return ret
return inner
def max(*args):
"""Finds the largest argument."""
ret = 0
for x in args:
ret = ret if x < ret else x
return ret
max = trace(max)
def foo():
max(-10, -1, -3)
foo()
def trace(f):
def inner(*args, **kwargs):
call = ", ".join(
[str(a) for a in args] + [f"{k}={v}" for k, v in kwargs]
)
print(f"{f.__name__}({call}) = ...")
ret = f(*args, **kwargs)
print(f"{f.__name__}({call}) = {ret}")
return ret
return inner
@trace
def max(*args):
"""Finds the largest argument."""
ret = 0
for x in args:
ret = ret if x < ret else x
return ret
def foo():
max(-10, -1, -3)
foo()
DEBUG = True
def trace(f):
# decoration time
if not DEBUG:
return f
def inner(*args, **kwargs):
# call time
call = ", ".join(
[str(a) for a in args] + [f"{k}={v}" for k, v in kwargs]
)
print(f"{f.__name__}({call}) = ...")
ret = f(*args, **kwargs)
print(f"{f.__name__}({call}) = {ret}")
return ret
return inner
@trace
def max(*args):
"""Finds the largest argument."""
ret = 0
for x in args:
ret = ret if x < ret else x
return ret
def foo():
max(-10, -1, -3)
foo()
DEBUG = True
def trace(f):
if not DEBUG:
return f
def inner(*args, **kwargs):
call = ", ".join(
[str(a) for a in args] + [f"{k}={v}" for k, v in kwargs]
)
print(f"{f.__name__}({call}) = ...")
ret = f(*args, **kwargs)
print(f"{f.__name__}({call}) = {ret}")
return ret
inner.__name__ = f.__name__
inner.__doc__ = f.__doc__
inner.__module__ = f.__module__
return inner
@trace
def max(*args):
"""Finds the largest argument."""
ret = 0
for x in args:
ret = ret if x < ret else x
return ret
def foo():
max(-10, -1, -3)
foo()
DEBUG = True
def update_wrapper(wrapped, wrapper):
for attr in ["__name__", "__doc__", "__module__"]:
setattr(wrapper, attr, getattr(wrapped, attr))
wrapper.__wrapped__ = wrapped
def trace(f):
if not DEBUG:
return f
def inner(*args, **kwargs):
call = ", ".join(
[str(a) for a in args] + [f"{k}={v}" for k, v in kwargs]
)
print(f"{f.__name__}({call}) = ...")
ret = f(*args, **kwargs)
print(f"{f.__name__}({call}) = {ret}")
return ret
update_wrapper(f, inner)
return inner
@trace
def max(*args):
"""Finds the largest argument."""
ret = 0
for x in args:
ret = ret if x < ret else x
return ret
def foo():
max(-10, -1, -3)
foo()
import functools
DEBUG = True
def update_wrapper(wrapped, wrapper):
for attr in ["__name__", "__doc__", "__module__"]:
setattr(wrapper, attr, getattr(wrapped, attr))
return wrapper
def trace(f):
if not DEBUG:
return f
wraps = functools.partial(update_wrapper, f)
@wraps
def inner(*args, **kwargs):
call = ", ".join(
[str(a) for a in args] + [f"{k}={v}" for k, v in kwargs]
)
print(f"{f.__name__}({call}) = ...")
ret = f(*args, **kwargs)
print(f"{f.__name__}({call}) = {ret}")
return ret
return inner
@trace
def max(*args):
"""Finds the largest argument."""
ret = 0
for x in args:
ret = ret if x < ret else x
return ret
def foo():
max(-10, -1, -3)
foo()
DEBUG = True
def update_wrapper(wrapped, wrapper):
for attr in ["__name__", "__doc__", "__module__"]:
setattr(wrapper, attr, getattr(wrapped, attr))
return wrapper
def wraps(f):
def deco(g):
update_wrapper(f, g)
return g
return deco
def trace(f):
if not DEBUG:
return f
@wraps(f)
def inner(*args, **kwargs):
call = ", ".join(
[str(a) for a in args] + [f"{k}={v}" for k, v in kwargs]
)
print(f"{f.__name__}({call}) = ...")
ret = f(*args, **kwargs)
print(f"{f.__name__}({call}) = {ret}")
return ret
return inner
@trace
def max(*args):
"""Finds the largest argument."""
ret = 0
for x in args:
ret = ret if x < ret else x
return ret
def foo():
max(-10, -1, -3)
foo()
import functools
DEBUG = True
def trace(f):
if not DEBUG:
return f
@functools.wraps(f)
def inner(*args, **kwargs):
call = ", ".join(
[str(a) for a in args] + [f"{k}={v}" for k, v in kwargs]
)
print(f"{f.__name__}({call}) = ...")
ret = f(*args, **kwargs)
print(f"{f.__name__}({call}) = {ret}")
return ret
return inner
@trace
def max(*args):
"""Finds the largest argument."""
ret = 0
for x in args:
ret = ret if x < ret else x
return ret
def foo():
max(-10, -1, -3)
foo()
import functools
import sys
DEBUG = True
# def trace(f):
# if not DEBUG:
# return f
#
# @functools.wraps(f)
# def inner(*args, **kwargs):
# call = ", ".join(
# [str(a) for a in args] + [f"{k}={v}" for k, v in kwargs]
# )
# print(f"{f.__name__}({call}) = ...")
# ret = f(*args, **kwargs)
# print(f"{f.__name__}({call}) = {ret}")
# return ret
#
# return inner
@trace(sys.stderr)
def max(*args):
"""Finds the largest argument."""
ret = 0
for x in args:
ret = ret if x < ret else x
return ret
deco = trace(sys.stderr)
max = deco(max)
def foo():
max(-10, -1, -3)
foo()
import functools
import sys
DEBUG = True
def trace(stream=sys.stdout):
def decorator(f):
if not DEBUG:
return f
@functools.wraps(f)
def inner(*args, **kwargs):
call = ", ".join(
[str(a) for a in args] + [f"{k}={v}" for k, v in kwargs]
)
print(f"{f.__name__}({call}) = ...", file=stream)
ret = f(*args, **kwargs)
print(f"{f.__name__}({call}) = {ret}", file=stream)
return ret
return inner
return decorator
@trace(sys.stderr)
def max(*args):
"""Finds the largest argument."""
ret = 0
for x in args:
ret = ret if x < ret else x
return ret
def foo():
max(-10, -1, -3)
foo()
import functools
import sys
DEBUG = True
def trace(f=None, *, stream=sys.stdout):
if f is None:
return functools.partial(trace, stream=stream)
if not DEBUG:
return f
@functools.wraps(f)
def inner(*args, **kwargs):
call = ", ".join(
[str(a) for a in args] + [f"{k}={v}" for k, v in kwargs]
)
print(f"{f.__name__}({call}) = ...", file=stream)
ret = f(*args, **kwargs)
print(f"{f.__name__}({call}) = {ret}", file=stream)
return ret
return inner
@trace
def max(*args):
"""Finds the largest argument."""
ret = 0
for x in args:
ret = ret if x < ret else x
return ret
def foo():
max(-10, -1, -3)
foo()
import time
import functools
def profile(f):
@functools.wraps(f)
def inner(*args, **kwargs):
start = time.perf_counter()
ret = f(*args, **kwargs)
elapsed = time.perf_counter() - start
inner.__total_time__ += elapsed
inner.__n_calls__ += 1
return ret
inner.__total_time__ = 0
inner.__n_calls__ = 0
return inner
@profile
def max(*args):
"""Finds the largest argument."""
ret = 0
for x in args:
ret = ret if x < ret else x
return ret
def foo():
max(-10, -1, -3)
foo()
print(max.__total_time__)
print(max.__n_calls__)
import time
import functools
def profile(f):
@functools.wraps(f)
def inner(*args, **kwargs):
start = time.perf_counter()
ret = f(*args, **kwargs)
elapsed = time.perf_counter() - start
inner.__total_time__ += elapsed
inner.__n_calls__ += 1
return ret
inner.__total_time__ = 0
inner.__n_calls__ = 0
return inner
def memoize(f):
cache = {}
@functools.wraps(f)
def inner(*args, **kwargs):
key = (args, frozenset(kwargs.items()))
if key not in cache:
cache[key] = f(*args, **kwargs)
return cache[key]
return inner
@profile
@memoize
def fib(n):
return 1 if n <= 1 else fib(n - 1) + fib(n - 2)
print(fib(20))
print(fib.__total_time__)
print(fib.__n_calls__)
import time
import functools
def profile(f):
@functools.wraps(f)
def inner(*args, **kwargs):
start = time.perf_counter()
ret = f(*args, **kwargs)
elapsed = time.perf_counter() - start
inner.__total_time__ += elapsed
inner.__n_calls__ += 1
return ret
inner.__total_time__ = 0
inner.__n_calls__ = 0
return inner
@profile
@functools.lru_cache(maxsize=None)
def fib(n):
return 1 if n <= 1 else fib(n - 1) + fib(n - 2)
print(fib(20))
print(fib.__total_time__)
print(fib.__n_calls__)
import functools
@functools.singledispatch
def json(obj):
assert False, f"{type(obj)} not supported: {obj}"
@json.register(int)
def _(i):
return str(i)
@json.register(str)
def _(s):
return f'"{s}"' # TODO: escape
@json.register(list)
def _(l):
elements = ", ".join(map(json, l))
return f"[{elements}]"
@json.register(dict)
def _(d):
elements = ", ".join(f'"{k}": {json(v)}' for k, v in d.items())
return f"{{{elements}}}"
xs = [1, 2, "hello", {'foo': []}]
print(json(xs))
@mizoru
Copy link

mizoru commented Sep 6, 2023

А домашки для этого прекрасного курса вот так вот просто не лежат тоже где-нибудь?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment