-
Notifications
You must be signed in to change notification settings - Fork 1
/
decorators.py
92 lines (72 loc) · 1.97 KB
/
decorators.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
"""
Decorators alter behaviour of functions.
© Denis Shelemekh, 2020
"""
from typing import Any
import time
import requests
def measure_time(func: Any) -> Any:
"""
Measures and prints execution time for function.
Args:
func: Function to monitor.
Returns:
inner function.
"""
def inner(*args, **kwargs):
start = time.time()
try:
return func(*args, **kwargs)
finally:
end = time.time() - start
print('%s.%s: %f' % (func.__module__, func.__name__, end - start))
return inner
def memoize(func: any) -> Any:
"""
Caches (string) results of function's execution.
Args:
func: Function to cache.
Returns:
inner function.
"""
_cache = {}
stale_time = 10 # seconds
def wrapper(*args, **kwargs):
name = func.__name__
# tuple is immutable, thus hashable, thus can be a key for dictionary
key = (name, args, frozenset(kwargs.items()))
if key in _cache:
value = _cache[key]
if (time.time() - value[1]) < stale_time:
return value[0]
result = func(*args, **kwargs)
_cache[key] = [result, time.time()]
return result
return wrapper
@measure_time
@memoize
def fetch_url(url: str) -> str:
"""
Example of decorators' usage.
Let's fetch the url and both measure the time of execution and cache results.
Args:
url: url to fetch.
Returns:
String - Status/encoding/length of request.
"""
res = requests.get(url)
ret = f"Status: {res.status_code}\n"
ret += f"Encoding: {res.encoding}\n"
ret += f"Content Length: {len(res.text)} bytes\n"
return ret
def main() -> None:
"""
Standard main function.
"""
print(fetch_url("https://python.org"))
print("")
print(fetch_url("https://python.org"))
time.sleep(11)
print(fetch_url("https://python.org"))
if __name__ == '__main__':
main()