From: Raymond Hettinger Date: Sat, 12 Oct 2013 23:04:39 +0000 (-0700) Subject: merge X-Git-Tag: v3.4.0a4~152 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=84fc7081f55f517062b35d0e0628cdfa4f1b9d55;p=thirdparty%2FPython%2Fcpython.git merge --- 84fc7081f55f517062b35d0e0628cdfa4f1b9d55 diff --cc Doc/library/functools.rst index 5eb86ec93c57,3c946e3eb28c..14e13519a43e --- a/Doc/library/functools.rst +++ b/Doc/library/functools.rst @@@ -205,112 -185,19 +205,124 @@@ The :mod:`functools` module defines th a default when the sequence is empty. If *initializer* is not given and *sequence* contains only one item, the first item is returned. + Equivalent to:: + + def reduce(function, iterable, initializer=None): + it = iter(iterable) + if initializer is None: + value = next(it) + else: + value = initializer + for element in it: + value = function(value, element) + return value + +.. decorator:: singledispatch(default) + + Transforms a function into a :term:`single-dispatch ` :term:`generic function`. + + To define a generic function, decorate it with the ``@singledispatch`` + decorator. Note that the dispatch happens on the type of the first argument, + create your function accordingly:: + + >>> from functools import singledispatch + >>> @singledispatch + ... def fun(arg, verbose=False): + ... if verbose: + ... print("Let me just say,", end=" ") + ... print(arg) + + To add overloaded implementations to the function, use the :func:`register` + attribute of the generic function. It is a decorator, taking a type + parameter and decorating a function implementing the operation for that + type:: + + >>> @fun.register(int) + ... def _(arg, verbose=False): + ... if verbose: + ... print("Strength in numbers, eh?", end=" ") + ... print(arg) + ... + >>> @fun.register(list) + ... def _(arg, verbose=False): + ... if verbose: + ... print("Enumerate this:") + ... for i, elem in enumerate(arg): + ... print(i, elem) + + To enable registering lambdas and pre-existing functions, the + :func:`register` attribute can be used in a functional form:: + + >>> def nothing(arg, verbose=False): + ... print("Nothing.") + ... + >>> fun.register(type(None), nothing) + + The :func:`register` attribute returns the undecorated function which + enables decorator stacking, pickling, as well as creating unit tests for + each variant independently:: + + >>> @fun.register(float) + ... @fun.register(Decimal) + ... def fun_num(arg, verbose=False): + ... if verbose: + ... print("Half of your number:", end=" ") + ... print(arg / 2) + ... + >>> fun_num is fun + False + + When called, the generic function dispatches on the type of the first + argument:: + + >>> fun("Hello, world.") + Hello, world. + >>> fun("test.", verbose=True) + Let me just say, test. + >>> fun(42, verbose=True) + Strength in numbers, eh? 42 + >>> fun(['spam', 'spam', 'eggs', 'spam'], verbose=True) + Enumerate this: + 0 spam + 1 spam + 2 eggs + 3 spam + >>> fun(None) + Nothing. + >>> fun(1.23) + 0.615 + + Where there is no registered implementation for a specific type, its + method resolution order is used to find a more generic implementation. + The original function decorated with ``@singledispatch`` is registered + for the base ``object`` type, which means it is used if no better + implementation is found. + + To check which implementation will the generic function choose for + a given type, use the ``dispatch()`` attribute:: + + >>> fun.dispatch(float) + + >>> fun.dispatch(dict) # note: default implementation + + + To access all registered implementations, use the read-only ``registry`` + attribute:: + + >>> fun.registry.keys() + dict_keys([, , , + , , + ]) + >>> fun.registry[float] + + >>> fun.registry[object] + + + .. versionadded:: 3.4 + + .. function:: update_wrapper(wrapper, wrapped, assigned=WRAPPER_ASSIGNMENTS, updated=WRAPPER_UPDATES) Update a *wrapper* function to look like the *wrapped* function. The optional