@@ -251,3 +251,96 @@ once more time again, and again, and again...
251251 methods as the target and delegates to it all requests it receives.
252252 However, the wrapper may alter the result by doing something either before
253253 or after it passes the request to the target.
254+
255+ Passing arguments to the wrapper
256+ ================================
257+
258+ Until now the examples use *simple* decorators. But what if the decorated
259+ function gets some arguments? This will cause ``TypeError`` exception that tell
260+ that "arguments are missed". This can be fixed with just passing arguments to
261+ the ``wrapper`` inner function.
262+
263+ .. code-block:: python
264+
265+ import logging
266+ from typing import Callable
267+
268+ logging.basicConfig(level=logging.INFO)
269+ logger = logging.getLogger(__name__)
270+
271+
272+ def log(func: Callable) -> Callable:
273+ def wrapper(x, y):
274+ logger.info("%s called", func.__name__)
275+ return func(x, y)
276+
277+ return wrapper
278+
279+
280+ @log
281+ def sum_numbers(x, y):
282+ return x + y
283+
284+ If case you're trying to make a generic decorator, you may pass ``*args`` and
285+ ``**kwargs`` instead of exact arguments:
286+
287+ .. code-block:: python
288+
289+ from typing import Callable
290+
291+
292+ def generic_decorator(func: Callable) -> Callable:
293+ def wrapper(*args, **kwargs):
294+ ... # do something before
295+ result = func(*args, **kwargs)
296+ ... # do something after
297+
298+ return result
299+
300+ return wrapper
301+
302+ Passing arguments to decorator
303+ ==============================
304+
305+ At last it's time to know how to pass arguments to the decorator.
306+ Here is a simple implementation of ``defer`` decorator which deferred
307+ the function execution for some time:
308+
309+ .. code-block:: python
310+
311+ import time
312+ from typing import Callable
313+
314+
315+ def defer(seconds: int = 3) -> Callable:
316+ def decorator(func: Callable) -> Callable:
317+ def wrapper(*args, **kwargs):
318+ started_at = time.perf_counter()
319+ time.sleep(seconds)
320+ result = func(*args, **kwargs)
321+ completed_in = round(time.perf_counter() - started_at, 2)
322+ print("Completed in %.2f" % completed_in)
323+
324+ return result
325+
326+ return wrapper
327+
328+ return decorator
329+
330+
331+ @defer()
332+ def function_a():
333+ return 42
334+
335+
336+ @defer(10)
337+ def function_b():
338+ return 24
339+
340+
341+ .. code-block::
342+
343+ function_a()
344+ Completed in 3.00
345+ function_b()
346+ Completed in 10.00
0 commit comments