Differences creating tuples and collections.namedtuples
tjreedy at udel.edu
Wed Feb 20 04:38:32 CET 2013
On 2/18/2013 7:18 PM, Steven D'Aprano wrote:
> Terry Reedy wrote:
>> On 2/18/2013 6:47 AM, John Reid wrote:
>>> I was hoping namedtuples could be used as replacements for tuples
>>> in all instances.
>> This is a mistake in the following two senses. First, tuple is a class
>> with instances while namedtuple is a class factory that produces
>> classes. (One could think of namedtuple as a metaclass, but it was not
>> implemented that way.)
> I think you have misunderstood.
Wrong, which should be evident to anyone who reads the entire paragraph
as the complete thought exposition it was meant to be. Beside which,
this negative ad hominem comment is irrelevant to the rest of your post
about the Liskov Substitution Principle.
The rest of the paragraph, in two more pieces:
>> Second, a tuple instance can have any length and
>> different instances can have different lengths. On the other hand, all
>> instances of a particular namedtuple class have a fixed length.
In other words, neither the namedtuple object nor any namedtuple class
object can fully substitute for the tuple class object. Nor can
instances of any namedtuple class fully substitute for instances of the
tuple class. Therefore, I claim, the hope that "namedtuples could be
used as replacements for tuples in all instances" is a futile hope,
however one interprets that hope.
>> This affects their initialization.
Part of the effect is independent of initialization. Even if namedtuples
were initialized by iterator, there would still be glitches. In
particular, even if John's named tuple class B *could* be initialized as
B((1,2,3)), it still could not be substituted for t in the code below.
>>> t = (1,2,3)
>>> type(t) is type(t[1:])
As far as read access goes, B effectively is a tuple. As soon as one
uses type() directly or indirectly (by creating new objects), there may
be problems. That is because the addition of field names *also* adds a
length constraint, which is a subtraction of flexibility.
Liskov Substitution Principle (LSP): I met this over 15 years ago
reading debates among OOP enthusiasts about whether Rectangle should be
a subclass of Square or Square a subclass of Rectangle, and similarly,
whether Ostrich can be a legitimate subclass of Bird.
The problem I see with the LSP for modeling either abstract or concrete
entities is that we in fact do define subclasses by subtraction or
limitation, as well as by augmentation, while the LSP only allows the
On answer to the conundrums above to to add Parallelepiped as a
superclass for both Square and Rectangle and Flying_bird as an
additional subclass of Bird. But then the question becomes: Does obeying
the LSP count as 'necessity' when one is trying to follow Ockham's
principle of not multiplying classes without necessity?
Terry Jan Reedy
More information about the Python-list