diff options
Diffstat (limited to 'docs/documentation.md')
-rw-r--r-- | docs/documentation.md | 80 |
1 files changed, 28 insertions, 52 deletions
diff --git a/docs/documentation.md b/docs/documentation.md index 162caae..bd2b4ad 100644 --- a/docs/documentation.md +++ b/docs/documentation.md @@ -1,17 +1,15 @@ -Decorators for Humans ----------------------------------- +# Decorators for Humans |Author | Michele Simionato| |---|---| |E-mail | michele.simionato@gmail.com| -|Version| 5.0.9 (2021-05-16)| +|Version| 5.0.9 (2021-09-11)| |Supports| Python 3.5, 3.6, 3.7, 3.8, 3.9| |Download page| http://pypi.python.org/pypi/decorator/5.0.9| |Installation| ``pip install decorator``| |License | BSD license| -Introduction ------------------------------------------ +## Introduction The ``decorator`` module is over ten years old, but still alive and kicking. It is used by several frameworks (IPython, scipy, authkit, @@ -22,8 +20,7 @@ supports Python versions greater than 3.4, versions 4.X supports Python versions back to 2.6; versions 3.X are able to support even Python 2.5 and 2.4. -What's New in version 5 ------------------------ +## What's New in version 5 Version 5 of the decorator module features a major simplification of the code base made possible by dropping support for Python releases @@ -35,8 +32,7 @@ functions the traceback is nicer than it used to be. Moreover, it is now possible to mimic the behavior of decorators defined with ``functool.wraps``: see the section about the ``kwsyntax`` flag below. -What's New in version 4 ------------------------ +## What's New in version 4 - **New documentation** There is now a single manual for all Python versions, so I took the @@ -75,8 +71,7 @@ What's New in version 4 From version 4.2 there is facility to define factories of decorators in a simple way, a feature requested by the users since a long time. -Usefulness of decorators ------------------------------------------------- +## Usefulness of decorators Python decorators are an interesting example of why syntactic sugar matters. In principle, their introduction in Python 2.4 changed @@ -106,8 +101,7 @@ You may find the source code for all the examples discussed here in the ``documentation.py`` file, which contains the documentation you are reading in the form of doctests. -Definitions ------------------------------------- +## Definitions Technically speaking, any Python object which can be called with one argument can be used as a decorator. However, this definition is somewhat too large @@ -136,8 +130,7 @@ obvious, especially if one wants to define proper decorators that can accept functions with any signature. A simple example will clarify the issue. -Statement of the problem ------------------------------- +## Statement of the problem A very common use case for decorators is the memoization of functions. A ``memoize`` decorator works by caching @@ -146,7 +139,7 @@ the function is called with the same input parameters the result is retrieved from the cache and not recomputed. There are many implementations of ``memoize`` in -https://wiki.python.org/moin/PythonDecoratorLibrary, +http://www.python.org/moin/PythonDecoratorLibrary, but they do not preserve the signature. In recent versions of Python you can find a sophisticated ``lru_cache`` decorator in the standard library's ``functools``. Here I am just @@ -222,8 +215,7 @@ TypeError: f1() takes exactly 1 positional argument (2 given) Notice that ``pydoc`` will give the right signature, but only in Python versions greater than 3.5. -The solution ------------------------------------------ +## The solution The solution is to provide a generic factory of generators, which hides the complexity of making signature-preserving decorators @@ -301,8 +293,7 @@ FullArgSpec(args=[], varargs=None, varkw=None, defaults=None, kwonlyargs=[], kwo ``` -A ``trace`` decorator ------------------------------------------------------- +## A ``trace`` decorator Here is an example of how to define a simple ``trace`` decorator, which prints a message whenever the traced function is called: @@ -361,8 +352,7 @@ FullArgSpec(args=['x', 'y'], varargs='args', varkw='kw', defaults=(1,), kwonlyar ``` -Function annotations ---------------------------------------------- +## Function annotations Python 3 introduced the concept of [function annotations]( http://www.python.org/dev/peps/pep-3107/): the ability @@ -416,9 +406,7 @@ This attribute exists for consistency with the behavior of Another attribute copied from the original function is ``__qualname__``, the qualified name. This attribute was introduced in Python 3.3. - -``decorator.decorator`` ---------------------------------------------- +## ``decorator.decorator`` It can become tedious to write a caller function (like the above ``_trace`` example) and then a trivial wrapper @@ -468,8 +456,7 @@ calling func with args (), {} ``` -Mimicking the behavior of functools.wrap ----------------------------------------- +## Mimicking the behavior of functools.wrap Often people are confused by the decorator module since, contrarily to ``functools.wraps`` in the standard library, it tries very hard @@ -551,8 +538,7 @@ positional, i.e. they belongs to the ``args`` tuple and not to ``kwargs``: ``` -Decorator factories -------------------------------------------- +## Decorator factories The `decorator` function can also be used to define factories of decorators, i.e. functions returning decorators. In general you can just write something @@ -683,8 +669,7 @@ TypeError: You are decorating a non function: <class '__main__.User'> Be careful! -``decorator(cls)`` --------------------------------------------- +## ``decorator(cls)`` The ``decorator`` facility can also produce a decorator starting from a class with the signature of a caller. In such a case the @@ -742,8 +727,7 @@ Here is the minimalistic usage: ``` -contextmanager -------------------------------------- +## contextmanager Python's standard library has the ``contextmanager`` decorator, which converts a generator function into a ``GeneratorContextManager`` @@ -780,11 +764,11 @@ a ``__call__`` method, so that they can be used as decorators, like so: ```python >>> ba = before_after('BEFORE', 'AFTER') >>> ->>> @ba +>>> @ba ... def hello(): ... print('hello') ... ->>> hello() +>>> hello() BEFORE hello AFTER @@ -808,8 +792,7 @@ instances of ``ContextManager``, a subclass of the standard library's an improved ``__call__`` method, which acts as a signature-preserving decorator. -The ``FunctionMaker`` class ---------------------------------------------------------------- +## The ``FunctionMaker`` class The ``decorator`` module also provides a ``FunctionMaker`` class, which is able to generate on-the-fly functions @@ -899,8 +882,7 @@ FullArgSpec(args=['a', 'b'], varargs=None, varkw=None, defaults=(None,), kwonlya ``` -Getting the source code ---------------------------------------------------- +## Getting the source code Internally, ``FunctionMaker.create`` uses ``exec`` to generate the decorated function. Therefore ``inspect.getsource`` will not work for @@ -923,8 +905,7 @@ def factorial(n, acc=1): ``` -Dealing with third-party decorators ------------------------------------------------------------------ +## Dealing with third-party decorators Sometimes on the net you find some cool decorator that you would like to include in your code. However, more often than not, the cool @@ -1047,8 +1028,7 @@ following: - returns a value without making a recursive call; or, - returns directly the result of a recursive call. -Python 3.5 coroutines ------------------------ +## Python 3.5 coroutines I am personally not using Python 3.5 coroutines yet. However, some users requested support for coroutines and since version 4.1 the @@ -1118,8 +1098,7 @@ function and the associate decorator was converting coroutines in coroutines; the caller in ``coro_to_func`` is a regular function and converts coroutines -> functions. -Multiple dispatch -------------------------------------------- +## Multiple dispatch There has been talk of implementing multiple dispatch functions (i.e. "generic functions") in Python for over ten years. Last year, @@ -1315,8 +1294,7 @@ product of the class precedence lists (or *Method Resolution Orders*, [MRO](http://www.python.org/2.3/mro.html) for short) of ``StrongRock`` and ``Scissors``, respectively. -Generic functions and virtual ancestors -------------------------------------------------- +## Generic functions and virtual ancestors In Python, generic functions are complicated by the existence of "virtual ancestors": superclasses which are not in the class hierarchy. @@ -1535,8 +1513,7 @@ call-next-method in Lisp, or to ``super`` in Python. Finally, let me notice that the decorator module implementation does not use any cache, whereas the ``singledispatch`` implementation does. -Caveats and limitations -------------------------------------------- +## Caveats and limitations In the present implementation, decorators generated by ``decorator`` can only be used on user-defined Python functions, methods or coroutines. @@ -1650,8 +1627,7 @@ than the function ``f`` here, so the real life performance penalty *could* be negligible. As always, the only way to know if there is a penalty in your specific use case is to measure it. -LICENSE (2-clause BSD) ---------------------------------------------- +## LICENSE (2-clause BSD) Copyright (c) 2005-2020, Michele Simionato All rights reserved. @@ -1682,4 +1658,4 @@ DAMAGE. If you use this software and you are happy with it, consider sending me a note, just to gratify my ego. On the other hand, if you use this software and -you are unhappy with it, send me a patch! +you are unhappy with it, send me a patch!
\ No newline at end of file |