[Python-checkins] r58975 - in python/trunk: Doc/library/collections.rst Lib/collections.py Lib/test/test_collections.py

M.-A. Lemburg mal at egenix.com
Thu Nov 15 12:06:27 CET 2007


I'm probably missing something, but why don't you name the
method "replace" instead of using a Python internal name for
it ?

On 2007-11-15 03:44, raymond.hettinger wrote:
> Author: raymond.hettinger
> Date: Thu Nov 15 03:44:53 2007
> New Revision: 58975
> 
> Modified:
>    python/trunk/Doc/library/collections.rst
>    python/trunk/Lib/collections.py
>    python/trunk/Lib/test/test_collections.py
> Log:
> Accept Issac Morland's suggestion for __replace__ to allow multiple replacements
> (suprisingly, this simplifies the signature, improves clarity, and is comparably fast).
> Update the docs to reflect a previous change to the function name.
> Add an example to the docs showing how to override the default __repr__ method.
> 
> 
> 
> Modified: python/trunk/Doc/library/collections.rst
> ==============================================================================
> --- python/trunk/Doc/library/collections.rst	(original)
> +++ python/trunk/Doc/library/collections.rst	Thu Nov 15 03:44:53 2007
> @@ -12,7 +12,7 @@
>  
>  This module implements high-performance container datatypes.  Currently,
>  there are two datatypes, :class:`deque` and :class:`defaultdict`, and
> -one datatype factory function, :func:`named_tuple`. Python already
> +one datatype factory function, :func:`namedtuple`. Python already
>  includes built-in containers, :class:`dict`, :class:`list`,
>  :class:`set`, and :class:`tuple`. In addition, the optional :mod:`bsddb`
>  module has a :meth:`bsddb.btopen` method that can be used to create in-memory
> @@ -25,7 +25,7 @@
>     Added :class:`defaultdict`.
>  
>  .. versionchanged:: 2.6
> -   Added :func:`named_tuple`.
> +   Added :func:`namedtuple`.
>  
>  
>  .. _deque-objects:
> @@ -348,14 +348,14 @@
>  
>  .. _named-tuple-factory:
>  
> -:func:`named_tuple` Factory Function for Tuples with Named Fields
> +:func:`namedtuple` Factory Function for Tuples with Named Fields
>  -----------------------------------------------------------------
>  
>  Named tuples assign meaning to each position in a tuple and allow for more readable,
>  self-documenting code.  They can be used wherever regular tuples are used, and
>  they add the ability to access fields by name instead of position index.
>  
> -.. function:: named_tuple(typename, fieldnames, [verbose])
> +.. function:: namedtuple(typename, fieldnames, [verbose])
>  
>     Returns a new tuple subclass named *typename*.  The new subclass is used to
>     create tuple-like objects that have fields accessable by attribute lookup as
> @@ -382,7 +382,7 @@
>  
>  Example::
>  
> -   >>> Point = named_tuple('Point', 'x y', verbose=True)
> +   >>> Point = namedtuple('Point', 'x y', verbose=True)
>     class Point(tuple):
>             'Point(x, y)'
>             __slots__ = ()
> @@ -395,8 +395,8 @@
>                 'Return a new dict mapping field names to their values'
>                 return dict(zip(('x', 'y'), self))
>             def __replace__(self, field, value):
> -               'Return a new Point object replacing one field with a new value'
> -               return Point(**dict(zip(('x', 'y'), self) + [(field, value)]))
> +               'Return a new Point object replacing specified fields with new values'
> +               return Point(**dict(self.__asdict__().items() + kwds.items()))
>             x = property(itemgetter(0))
>             y = property(itemgetter(1))
>  
> @@ -414,7 +414,7 @@
>  Named tuples are especially useful for assigning field names to result tuples returned
>  by the :mod:`csv` or :mod:`sqlite3` modules::
>  
> -   EmployeeRecord = named_tuple('EmployeeRecord', 'name, age, title, department, paygrade')
> +   EmployeeRecord = namedtuple('EmployeeRecord', 'name, age, title, department, paygrade')
>  
>     from itertools import starmap
>     import csv
> @@ -453,14 +453,14 @@
>        >>> p.__asdict__()
>        {'x': 11, 'y': 22}
>        
> -.. method:: somenamedtuple.__replace__(field, value)
> +.. method:: somenamedtuple.__replace__(kwargs)
>  
> -   Return a new instance of the named tuple replacing the named *field* with a new *value*:
> +   Return a new instance of the named tuple replacing specified fields with new values:
>  
>  ::
>  
>        >>> p = Point(x=11, y=22)
> -      >>> p.__replace__('x', 33)
> +      >>> p.__replace__(x=33)
>        Point(x=33, y=22)
>  
>        >>> for recordnum, record in inventory:
> @@ -476,11 +476,22 @@
>        >>> p.__fields__                                  # view the field names
>        ('x', 'y')
>  
> -      >>> Color = named_tuple('Color', 'red green blue')
> -      >>> Pixel = named_tuple('Pixel', Point.__fields__ + Color.__fields__)
> +      >>> Color = namedtuple('Color', 'red green blue')
> +      >>> Pixel = namedtuple('Pixel', Point.__fields__ + Color.__fields__)
>        >>> Pixel(11, 22, 128, 255, 0)
>        Pixel(x=11, y=22, red=128, green=255, blue=0)'
>  
> +Since a named tuple is a regular Python class, it is easy to add or change
> +functionality.  For example, the display format can be changed by overriding
> +the :meth:`__repr__` method:
> +
> +::
> +
> +    >>> Point = namedtuple('Point', 'x y')
> +    >>> Point.__repr__ = lambda self: 'Point(%.3f, %.3f)' % self
> +    >>> Point(x=10, y=20)
> +    Point(10.000, 20.000)
> +
>  .. rubric:: Footnotes
>  
>  .. [#] For information on the star-operator see
> 
> Modified: python/trunk/Lib/collections.py
> ==============================================================================
> --- python/trunk/Lib/collections.py	(original)
> +++ python/trunk/Lib/collections.py	Thu Nov 15 03:44:53 2007
> @@ -24,7 +24,7 @@
>      11
>      >>> Point(**d)                      # convert from a dictionary
>      Point(x=11, y=22)
> -    >>> p.__replace__('x', 100)         # __replace__() is like str.replace() but targets a named field
> +    >>> p.__replace__(x=100)            # __replace__() is like str.replace() but targets named fields
>      Point(x=100, y=22)
>  
>      """
> @@ -62,9 +62,9 @@
>          def __asdict__(self, dict=dict, zip=zip):
>              'Return a new dict mapping field names to their values'
>              return dict(zip(%(field_names)r, self))
> -        def __replace__(self, field, value, dict=dict, zip=zip):
> -            'Return a new %(typename)s object replacing one field with a new value'
> -            return %(typename)s(**dict(zip(%(field_names)r, self) + [(field, value)]))  \n''' % locals()
> +        def __replace__(self, **kwds):
> +            'Return a new %(typename)s object replacing specified fields with new values'
> +            return %(typename)s(**dict(self.__asdict__().items() + kwds.items()))  \n''' % locals()
>      for i, name in enumerate(field_names):
>          template += '        %s = property(itemgetter(%d))\n' % (name, i)
>      if verbose:
> @@ -98,6 +98,10 @@
>      p = Point(x=10, y=20)
>      assert p == loads(dumps(p))
>  
> +    # test and demonstrate ability to override methods
> +    Point.__repr__ = lambda self:  'Point(%.3f, %.3f)' % self
> +    print p
> +
>      import doctest
>      TestResults = namedtuple('TestResults', 'failed attempted')
>      print TestResults(*doctest.testmod())
> 
> Modified: python/trunk/Lib/test/test_collections.py
> ==============================================================================
> --- python/trunk/Lib/test/test_collections.py	(original)
> +++ python/trunk/Lib/test/test_collections.py	Thu Nov 15 03:44:53 2007
> @@ -40,7 +40,7 @@
>          self.assert_('__dict__' not in dir(p))                              # verify instance has no dict
>          self.assert_('__weakref__' not in dir(p))
>          self.assertEqual(p.__fields__, ('x', 'y'))                          # test __fields__ attribute
> -        self.assertEqual(p.__replace__('x', 1), (1, 22))                    # test __replace__ method
> +        self.assertEqual(p.__replace__(x=1), (1, 22))                       # test __replace__ method
>          self.assertEqual(p.__asdict__(), dict(x=11, y=22))                  # test __dict__ method
>  
>          # Verify that __fields__ is read-only
> _______________________________________________
> Python-checkins mailing list
> Python-checkins at python.org
> http://mail.python.org/mailman/listinfo/python-checkins

-- 
Marc-Andre Lemburg
eGenix.com

Professional Python Services directly from the Source  (#1, Nov 15 2007)
>>> Python/Zope Consulting and Support ...        http://www.egenix.com/
>>> mxODBC.Zope.Database.Adapter ...             http://zope.egenix.com/
>>> mxODBC, mxDateTime, mxTextTools ...        http://python.egenix.com/
________________________________________________________________________

:::: Try mxODBC.Zope.DA for Windows,Linux,Solaris,MacOSX for free ! ::::


   eGenix.com Software, Skills and Services GmbH  Pastor-Loeh-Str.48
    D-40764 Langenfeld, Germany. CEO Dipl.-Math. Marc-Andre Lemburg
           Registered at Amtsgericht Duesseldorf: HRB 46611


More information about the Python-checkins mailing list