From 9a359210aaa7d9e0aa85f5a2084e7665bf0dae25 Mon Sep 17 00:00:00 2001 From: Raymond Hettinger Date: Mon, 7 Jan 2008 20:07:38 +0000 Subject: [PATCH] Cleanup named tuple subclassing example. --- Doc/library/collections.rst | 22 ++++++++++++---------- Lib/collections.py | 7 ++++--- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/Doc/library/collections.rst b/Doc/library/collections.rst index 8f9ac8ea2e2..e5b4dd965d3 100644 --- a/Doc/library/collections.rst +++ b/Doc/library/collections.rst @@ -365,7 +365,7 @@ they add the ability to access fields by name instead of position index. The *fieldnames* are a single string with each fieldname separated by whitespace and/or commas (for example 'x y' or 'x, y'). Alternatively, the *fieldnames* - can be specified as a list of strings (such as ['x', 'y']). + can be specified with a sequence of strings (such as ['x', 'y']). Any valid Python identifier may be used for a fieldname except for names starting with an underscore. Valid identifiers consist of letters, digits, @@ -478,7 +478,7 @@ three additional methods and one attribute. Point(x=33, y=22) >>> for partnum, record in inventory.items(): - ... inventory[partnum] = record._replace(price=newprices[partnum], updated=time.now()) + inventory[partnum] = record._replace(price=newprices[partnum], timestamp=time.now()) .. attribute:: somenamedtuple._fields @@ -515,13 +515,15 @@ a fixed-width print format:: @property def hypot(self): return (self.x ** 2 + self.y ** 2) ** 0.5 - def __repr__(self): - return 'Point(x=%.3f, y=%.3f, hypot=%.3f)' % (self.x, self.y, self.hypot) + def __str__(self): + return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) - >>> print Point(3, 4),'\n', Point(2, 5), '\n', Point(9./7, 6) - Point(x=3.000, y=4.000, hypot=5.000) - Point(x=2.000, y=5.000, hypot=5.385) - Point(x=1.286, y=6.000, hypot=6.136) + >>> for p in Point(3,4), Point(14,5), Point(9./7,6): + print p + + Point: x= 3.000 y= 4.000 hypot= 5.000 + Point: x=14.000 y= 5.000 hypot=14.866 + Point: x= 1.286 y= 6.000 hypot= 6.136 Another use for subclassing is to replace performance critcal methods with faster versions that bypass error-checking and localize variable access:: @@ -531,8 +533,8 @@ faster versions that bypass error-checking and localize variable access:: def _replace(self, _map=map, **kwds): return self._make(_map(kwds.pop, ('x', 'y'), self)) -Default values can be implemented by starting with a prototype instance -and customizing it with :meth:`_replace`:: +Default values can be implemented by using :meth:`_replace`:: to +customize a prototype instance:: >>> Account = namedtuple('Account', 'owner balance transaction_count') >>> model_account = Account('', 0.0, 0) diff --git a/Lib/collections.py b/Lib/collections.py index 51184a430bd..c19821bb396 100644 --- a/Lib/collections.py +++ b/Lib/collections.py @@ -120,10 +120,11 @@ if __name__ == '__main__': @property def hypot(self): return (self.x ** 2 + self.y ** 2) ** 0.5 - def __repr__(self): - return 'Point(x=%.3f, y=%.3f, hypot=%.3f)' % (self.x, self.y, self.hypot) + def __str__(self): + return 'Point: x=%6.3f y=%6.3f hypot=%6.3f' % (self.x, self.y, self.hypot) - print Point(3, 4),'\n', Point(2, 5), '\n', Point(9./7, 6) + for p in Point(3,4), Point(14,5), Point(9./7,6): + print p class Point(namedtuple('Point', 'x y')): 'Point class with optimized _make() and _replace() without error-checking'