[Python-ideas] recorarray: a mutable alternative to namedtuple
Steven D'Aprano
steve at pearwood.info
Sat Mar 28 14:37:09 CET 2015
On Fri, Mar 27, 2015 at 04:13:46PM -0700, Andrew Barnert wrote:
> On Mar 27, 2015, at 06:22, Joao S. O. Bueno <jsbueno at python.org.br> wrote:
[...]
> > The Python equivalent of a C Struct.
>
> But a C struct is not a subtype of, or substitutable for, a C array.
> It's not indexable. And the same is true with the equivalents in other
> languages. In fact, the dichotomy between struct--heterogeneous
> collection of fixed named fields--and array--homogeneous collection of
> indexed fields--goes back way before C. So, if you want the equivalent
> of a C struct, there's no reason to make it an iterable in Python.
Joao said "The Python equivalent of a C struct", not "a C struct".
Python is not C, and Python data types are not limited to what C does.
Python strings aren't limited to C null-delimited strings, and Python
ints aren't limited to what C ints can do.
I think the original thread was quite explicit about what is wanted:
something like a mutable equivalent to namedtuple. Namedtuples are used
in Python where C would use a struct, or Pascal a record, except that
namedtuples (being tuples) are immutable. I think it's quite reasonable
to want a mutable version.
Effectively, namedtuple is just a convenience function for wrapping up a
bunch of nice-to-have but not essential functionality around an
immutable struct. Python got by with unnamed tuples for over a decade,
so it's not like we *have* to have namedtuples. But having got them,
would we go back to using regular tuples as a struct? Hell no. Having
named fields is so much better.
> And a class already is the Python of a C struct, it's just that it can
> do _more_ than a C struct.
This is why it is unfair to insist that a Python equivalent of a C
struct be limited to what C structs do.
> > Just that.
> > An easy to create class, with named fields,
>
> Which is easy to do: just create a class, and create its fields in the
> __init__ method (or, in some cases, it's acceptable to use class
> attributes as "default values" for instance attributes).
If this is so easy, why we have namedtuple *and* SimpleNamespace
in the standard library. Are they both mistakes?
SimpleNamespace is especially interesting. The docs say:
"However, for a structured record type use namedtuple() instead."
https://docs.python.org/3/library/types.html#types.SimpleNamespace
which is great if you want an *immutable* structured record type, but
not if you want a mutable one.
Which brings us back to where this thread started: a request for a
mutable version of namedtuple. That's trickier than namedtuple, because
we don't have a mutable version of a tuple to inherit from. Lists won't
do the job, because they have a whole lot of functionality that are
inappropriate, e.g. sort, reverse, pop methods.
That makes it harder to create a mutable structured record type, not
simpler.
Think about the functional requirements:
- it should be semantically a struct, not a list or array;
- with a fixed set of named fields;
- fields should be ordered: a record with fields foo and bar is not the
same as a record with fields bar and foo;
- accessing fields by index would be a Nice To Have, but not essential;
- but iteration is essential, for sequence unpacking;
- values in the fields must be mutable;
- it should support equality, but not hashing (since it is mutable);
- it must have a nice repr and/or str;
- being mutable, it may directly or indirectly contain a reference to
itself (e.g. x.field = x) so it needs to deal with that correctly;
- support for pickle;
- like namedtuple, it may benefit from a handful of methods such as
'_asdict', '_fields', '_make', '_replace' or similar.
Does this sound easy to write? Well, sure, in the big picture, it's
hardly a 100,000 line application. But it's not a trivial class.
--
Steve
More information about the Python-ideas
mailing list