[Python-ideas] namedtuple baseclass
Steven D'Aprano
steve at pearwood.info
Sun Jan 12 12:43:01 CET 2014
On Sun, Jan 12, 2014 at 07:17:56PM +1100, Chris Angelico wrote:
> On Sun, Jan 12, 2014 at 6:53 PM, Andrew Barnert <abarnert at yahoo.com> wrote:
> > So to satisfy this use case, you'd either need an actual namedtuple
> > base class instead of an abc, or an abc that adds some API for
> > getting the field names (or name-value pairs). Either of which seems
> > reasonable--except for the odd quirk of having a public API in a
> > class that's prefixed with an underscore. (If it's not prefixed with
> > an underscore, it can conflict with a field name, which defeats the
> > whole purpose of namedtuple.)
> >
>
> Is compatibility with the current namedtuple important, or can this be
> done another way? For instance, the fields could be retrieved with
> __getitem__ instead:
It's a tuple. It already uses __getitem__ to return items indexed by
position. Adding magic so that obj["fields"] is an alias for
obj._fields is, well, horrible.
> # Hacking it in with a subclass. Gives no benefit
> # but is a proof of concept.
> class Point(namedtuple('Point', ['x', 'y'])):
> def __getitem__(self, which):
> if which=="fields": return self._fields
> return super().__getitem__(which)
I think you missed that namedtuple like objects written in C don't
have a _fields attribute, e.g. os.stat_result. If you're going to insist
that they add special handling in __getitem__, wouldn't it just be cleaner and simpler
to get them to add a _fields attribute?
So...
* An ABC for namedtuple as agreed by Raymond and Guido wouldn't include
any extra functionality beyond Sequence, so it doesn't guarantee the
existence of _fields; that doesn't satisfy the use-case.
* An actual namedtuple superclass only works for the namedtuple factory
function, not for C namedtuple-like types.
Both could be fixed -- Python could define a namedtuple superclass, and
all relevant C types like os.stat_result could be changed to inherit
from them. (But what of those which don't?) Or the ABC could be extended
to include a promise of _fields, but that would exclude C types. Either
way, in order to satisfy this use-case, there would be a whole lot of
changes needed.
Or, you can duck-type:
if isinstance(o, tuple):
try:
fields = o._fields
except AttributeError:
fields = ... # fall back
Have I missed something?
--
Steven
More information about the Python-ideas
mailing list