[Python-checkins] r79750 - in python/trunk: Doc/library/functools.rst Lib/functools.py Misc/NEWS

Jack Diederich jackdied at gmail.com
Sun Apr 4 20:57:36 CEST 2010


1) Woo for the total_ordering decorator.
2) did you mean to yank "Issue #8294" from NEWS?

On Sun, Apr 4, 2010 at 2:34 PM, raymond.hettinger
<python-checkins at python.org> wrote:
> Author: raymond.hettinger
> Date: Sun Apr  4 20:34:45 2010
> New Revision: 79750
>
> Log:
> Add functools.CmpToKey()
>
> Modified:
>   python/trunk/Doc/library/functools.rst
>   python/trunk/Lib/functools.py
>   python/trunk/Misc/NEWS
>
> Modified: python/trunk/Doc/library/functools.rst
> ==============================================================================
> --- python/trunk/Doc/library/functools.rst      (original)
> +++ python/trunk/Doc/library/functools.rst      Sun Apr  4 20:34:45 2010
> @@ -17,6 +17,28 @@
>
>  The :mod:`functools` module defines the following functions:
>
> +..  function:: CmpToKey(func)
> +
> +    Transform an old-style comparison function to a key-function.  Used with
> +    tools that accept key functions (such as :func:`sorted`, :func:`min`,
> +    :func:`max`, :func:`heapq.nlargest`, :func:`heapq.nsmallest`,
> +    :func:`itertools.groupby`).
> +    This function is primarily used as a transition tool for programs
> +    being converted to Py3.x where comparison functions are no longer
> +    supported.
> +
> +    A compare function is any callable that accept two arguments, compares
> +    them, and returns a negative number for less-than, zero for equality,
> +    or a positive number for greater-than.  A key function is a callable
> +    that accepts one argument and returns another value that indicates
> +    the position in the desired collation sequence.
> +
> +    Example::
> +
> +        sorted(iterable, key=CmpToKey(locale.strcoll))  # locale-aware sort order
> +
> +   .. versionadded:: 2.7
> +
>  .. function:: total_ordering(cls)
>
>    Given a class defining one or more rich comparison ordering methods, this
>
> Modified: python/trunk/Lib/functools.py
> ==============================================================================
> --- python/trunk/Lib/functools.py       (original)
> +++ python/trunk/Lib/functools.py       Sun Apr  4 20:34:45 2010
> @@ -49,3 +49,48 @@
>     """
>     return partial(update_wrapper, wrapped=wrapped,
>                    assigned=assigned, updated=updated)
> +
> +def total_ordering(cls):
> +    'Class decorator that fills-in missing ordering methods'
> +    convert = {
> +        '__lt__': [('__gt__', lambda self, other: other < self),
> +                   ('__le__', lambda self, other: not other < self),
> +                   ('__ge__', lambda self, other: not self < other)],
> +        '__le__': [('__ge__', lambda self, other: other <= self),
> +                   ('__lt__', lambda self, other: not other <= self),
> +                   ('__gt__', lambda self, other: not self <= other)],
> +        '__gt__': [('__lt__', lambda self, other: other > self),
> +                   ('__ge__', lambda self, other: not other > self),
> +                   ('__le__', lambda self, other: not self > other)],
> +        '__ge__': [('__le__', lambda self, other: other >= self),
> +                   ('__gt__', lambda self, other: not other >= self),
> +                   ('__lt__', lambda self, other: not self >= other)]
> +    }
> +    roots = set(dir(cls)) & set(convert)
> +    assert roots, 'must define at least one ordering operation: < > <= >='
> +    root = max(roots)       # prefer __lt __ to __le__ to __gt__ to __ge__
> +    for opname, opfunc in convert[root]:
> +        if opname not in roots:
> +            opfunc.__name__ = opname
> +            opfunc.__doc__ = getattr(int, opname).__doc__
> +            setattr(cls, opname, opfunc)
> +    return cls
> +
> +def CmpToKey(mycmp):
> +    'Convert a cmp= function into a key= function'
> +    class K(object):
> +        def __init__(self, obj, *args):
> +            self.obj = obj
> +        def __lt__(self, other):
> +            return mycmp(self.obj, other.obj) < 0
> +        def __gt__(self, other):
> +            return mycmp(self.obj, other.obj) > 0
> +        def __eq__(self, other):
> +            return mycmp(self.obj, other.obj) == 0
> +        def __le__(self, other):
> +            return mycmp(self.obj, other.obj) <= 0
> +        def __ge__(self, other):
> +            return mycmp(self.obj, other.obj) >= 0
> +        def __ne__(self, other):
> +            return mycmp(self.obj, other.obj) != 0
> +    return K
>
> Modified: python/trunk/Misc/NEWS
> ==============================================================================
> --- python/trunk/Misc/NEWS      (original)
> +++ python/trunk/Misc/NEWS      Sun Apr  4 20:34:45 2010
> @@ -57,6 +57,12 @@
>
>  - collections.Counter() now supports a subtract() method.
>
> +- the functools module now has a total_ordering() class decorator
> +  to simplify the specifying rich comparisons.
> +
> +- The functools module also adds CmpToKey() as a tool to transition
> +  old-style comparison functions to new-style key-functions.
> +
>  - Issue #8294: The Fraction constructor now accepts Decimal and float
>   instances directly.
>
> _______________________________________________
> Python-checkins mailing list
> Python-checkins at python.org
> http://mail.python.org/mailman/listinfo/python-checkins
>


More information about the Python-checkins mailing list