205 lines
5.8 KiB
Python
Executable File
205 lines
5.8 KiB
Python
Executable File
import itertools
|
|
import functools
|
|
from time import perf_counter, sleep
|
|
import sys
|
|
|
|
|
|
def do_twice(func):
|
|
@functools.wraps(func)
|
|
def wrapper(*args, **kwargs):
|
|
for _ in itertools.repeat(None, 2):
|
|
func(*args, **kwargs)
|
|
return func(*args, **kwargs)
|
|
return wrapper
|
|
|
|
|
|
def timer(func):
|
|
@functools.wraps(func)
|
|
def wrapper_timer(*args, **kwargs):
|
|
start_time = perf_counter()
|
|
value = func(*args, **kwargs)
|
|
end_time = perf_counter()
|
|
run_time = end_time - start_time
|
|
print(f'Finished {func.__name__!r} in {run_time:.4f} secs')
|
|
return value
|
|
return wrapper_timer
|
|
|
|
|
|
def debug(func):
|
|
""" Print the function signature and return the value """
|
|
@functools.wraps(func)
|
|
def wrapper_debug(*args, **kwargs):
|
|
args_repr = [repr(a) for a in args]
|
|
kwargs_repr = [f'{k}={v!r}' for k, v in kwargs.items()]
|
|
signature = ', '.join(args_repr + kwargs_repr)
|
|
print(f'Calling {func.__name__}({signature})')
|
|
value = func(*args, **kwargs)
|
|
print(f'{func.__name__!r} returned {value!r}')
|
|
return value
|
|
return wrapper_debug
|
|
|
|
|
|
def slow_down(func):
|
|
@functools.wraps(func)
|
|
def wrapper_slow_down(*args, **kwargs):
|
|
sleep(1)
|
|
return func(*args, **kwargs)
|
|
return wrapper_slow_down
|
|
|
|
|
|
def repeat(num: int):
|
|
def decorator_repeat(func: callable):
|
|
@functools.wraps(func)
|
|
def wrapper_repeat(*args: list, **kwargs: dict):
|
|
for _ in range(num):
|
|
value = func(*args, **kwargs)
|
|
return value
|
|
return wrapper_repeat
|
|
return decorator_repeat
|
|
|
|
|
|
def repeatN(_func=None, *, num=2):
|
|
def decorator_repeatN(func):
|
|
@functools.wraps(func)
|
|
def wrapper_repeatN(*args, **kwargs):
|
|
for _ in range(num):
|
|
value = func(*args, **kwargs)
|
|
return value
|
|
return wrapper_repeatN
|
|
|
|
if _func is None:
|
|
return decorator_repeatN
|
|
else:
|
|
return decorator_repeatN(_func)
|
|
|
|
|
|
def repeat_partial(func=None, *, num=2):
|
|
if func is None:
|
|
return functools.partial(repeat_partial, num=num)
|
|
|
|
@functools.wraps(func)
|
|
def repeat_partial_wrapper(*args, **kwargs):
|
|
for _ in range(num):
|
|
value = func(*args, **kwargs)
|
|
return value
|
|
return repeat_partial_wrapper
|
|
|
|
|
|
# def count_calls(func: callable):
|
|
# @functools.wraps(func)
|
|
# def wrapper_count_calls(*args, **kwargs):
|
|
# wrapper_count_calls.num_calls += 1
|
|
# print(f'Call {wrapper_count_calls.num_calls} of {func.__name__!r}')
|
|
# return func(*args, **kwargs)
|
|
# wrapper_count_calls.num_calls = 0
|
|
# print(wrapper_count_calls.num_calls)
|
|
# return wrapper_count_calls
|
|
|
|
|
|
# def count_calls(func: callable):
|
|
# num_calls = 0
|
|
# print(num_calls)
|
|
# @functools.wraps(func)
|
|
# def wrapper_count_calls(*args, **kwargs):
|
|
# nonlocal num_calls
|
|
# num_calls += 1
|
|
# print(f'Call {num_calls} of {func.__name__}')
|
|
# return func(*args, **kwargs)
|
|
# return wrapper_count_calls
|
|
|
|
|
|
def count_calls(func=None, *, num=0):
|
|
if func is None:
|
|
return functools.partial(count_calls, num=num)
|
|
|
|
@functools.wraps(func)
|
|
def wrapper_count_calls(*args, **kwargs):
|
|
wrapper_count_calls.num += 1
|
|
print(f'Call {wrapper_count_calls.num} of {func.__name__}')
|
|
return func(*args, **kwargs)
|
|
wrapper_count_calls.num = num
|
|
return wrapper_count_calls
|
|
|
|
|
|
class Counter(object):
|
|
"""docstring for Counter"""
|
|
def __init__(self, func):
|
|
print('start init')
|
|
super(Counter, self).__init__()
|
|
functools.update_wrapper(self, func)
|
|
self.func = func
|
|
self.num_calls = 0
|
|
print('finished init')
|
|
|
|
def __call__(self, *args, **kwargs):
|
|
print('start call')
|
|
self.num_calls += 1
|
|
print(f'Call {self.num_calls} of {self.func.__name__!r}')
|
|
print('finished call')
|
|
return self.func(*args, **kwargs)
|
|
|
|
|
|
# class slowDown(object):
|
|
# """docstring for slowDown"""
|
|
# def __init__(self, rate):
|
|
# if callable(rate):
|
|
# self.func = rate
|
|
# self.rate = 1
|
|
# else:
|
|
# self.rate = rate
|
|
|
|
# def __get__(self, obj, type=None):
|
|
# return functools.partial(self, obj)
|
|
|
|
# def __call__(self, *args, **kwargs):
|
|
# if not hasattr(self, 'func'):
|
|
# self.func = args[0]
|
|
# return self
|
|
# sleep(self.rate)
|
|
# self.func(*args, **kwargs)
|
|
|
|
|
|
class slowDown(object):
|
|
"""docstring for Slow_Down"""
|
|
def __init__(self, rate=1):
|
|
print('init')
|
|
self.rate = rate
|
|
|
|
def __call__(self, func):
|
|
@functools.wraps(func)
|
|
def wrapper(*args, **kwargs):
|
|
print('wrapper')
|
|
sleep(self.rate)
|
|
func(*args, **kwargs)
|
|
print('call finished')
|
|
print(self, func)
|
|
return wrapper
|
|
|
|
|
|
# class slowDown(object):
|
|
# """docstring for slowDown"""
|
|
# def __init__(self, rate):
|
|
# if callable(rate):
|
|
# self.func = rate
|
|
# self.rate = 1
|
|
# print(f'no args, {locals()}, func={self.func}, rate={self.rate},\
|
|
# self={self}')
|
|
# else:
|
|
# self.rate = rate
|
|
# print(f'args set, rate={self.rate}')
|
|
|
|
# def __get__(self, obj, type=None):
|
|
# print(f'get called, self={self}, obj={obj}, type={type}')
|
|
# return functools.partial(self, obj)
|
|
|
|
# def __call__(self, *args, **kwargs):
|
|
# print(f'call called, rate={self.rate}, args={args}'
|
|
# f', kwargs={kwargs} ,self={self}')
|
|
# print(f'locals = {locals()}')
|
|
# if not hasattr(self, 'func'):
|
|
# self.func = args[0]
|
|
# print(f'args set, setting self.func to {self.func}')
|
|
# return self
|
|
# sleep(self.rate)
|
|
# self.func(*args, **kwargs)
|