Created
September 28, 2018 18:04
-
-
Save matklad/9ab00a4d60e91d6c1e7b49dac5623f85 to your computer and use it in GitHub Desktop.
decorators.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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__) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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__) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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__) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
А домашки для этого прекрасного курса вот так вот просто не лежат тоже где-нибудь?