after()
Create a function that only invokes the provided function after it has been called a specified number of times.
Implementation
Accepts (func, n) or (n, func). The wrapped function will only execute the original `func` on the nth and subsequent calls; before that, it returns None. Parameters: a : Callable[..., R] or int The function to wrap or the number of calls to wait before invoking. b : int or Callable[..., R] The number of calls to wait before invoking or the function to wrap. Returns: A wrapped function that executes `func` only after the specified number of invocations.
Example
def greet():
return "Hello!"
greet_after_3 = after(greet, 3)
greet_after_3() # None
greet_after_3() # None
greet_after_3() # "Hello!"
Expected output: Function that prints only after being called 3 times
Source Code
def after(a: Any, b: Any) -> Callable[..., Optional[R]]:
if callable(a) and isinstance(b, int):
func, times = a, b
elif isinstance(a, int) and callable(b):
times, func = a, b # swapped
else:
raise TypeError("after expects (func, int) or (int, func)")
count = [0]
def wrapper(*args: Any, **kwargs: Any) -> Optional[R]:
count[0] += 1
if count[0] >= max(times, 1):
return func(*args, **kwargs) # type: ignore
return None
wrapper.__name__ = func.__name__
wrapper.__doc__ = func.__doc__
wrapper.__wrapped__ = func # type: ignore
return wrapper