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.
This commit is contained in:
Raymond Hettinger 2007-11-15 02:44:53 +00:00
parent b5e5d0741a
commit eeeb9c4445
3 changed files with 33 additions and 18 deletions

View file

@ -24,7 +24,7 @@ def namedtuple(typename, field_names, verbose=False):
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 namedtuple(typename, field_names, verbose=False):
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 @@ if __name__ == '__main__':
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())