[Python-ideas] recorarray: a mutable alternative to namedtuple

Andrew Barnert abarnert at yahoo.com
Sat Mar 28 02:09:03 CET 2015


On Mar 27, 2015, at 16:29, Luciano Ramalho <luciano at ramalho.org> wrote:
> 
> On Fri, Mar 27, 2015 at 8:13 PM, Andrew Barnert
> <abarnert at yahoo.com.dmarc.invalid> wrote:
>> So, if you want the equivalent of a C struct, there's no reason to make it an iterable in Python.
> 
> Yes, there is: iterable unpacking.

Why?

You can't do the equivalent in C or any of its descendants (or most other languages with a struct/record type, or most pedagogical or theoretical struct/record concepts). Nor can you do anything even vaguely similar. So why would anyone expect that "the equivalent of a C struct" in Python should be able to do something that a C struct, and its equivalents in other languages, can't?

Also, the desire to _not_ have to use iterable unpacking is why we have namedtuple (and structseq in the C API) in the first place: to make tuples that can be used as records, not the other way around. A namedtuple stat result allows your users to access the fields by name instead of by index, which not only makes their code more readable, it also means stat can return different sets of extra fields on different platforms and in new versions without breaking their code. Even in C, this is important: because you access the PyObject fields by name, I can hand you a PyList* cast to a PyObject* and you can use it; if C allowed you to access it by iterable unpacking and you did so, I'd instead have to copy the PyObject fields of the PyList into a new PyObject that didn't have any extra 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).
> 
> Boilerplate with lots of repetition, with little added value. For
> example, in a basic __init__ each attribute name usually occurs three
> times: as an argument name in the method declaration, and then twice
> when it's assigned to self. Ruby does much better, for example.

Let's compare some C code and the equivalent Python:

    struct Person {
        const char *name;
        int age;
    }
    struct Person person_make(const char *name, int age) {
        struct Person p;
        p.name = strdup(name);
        p.age = age;
        return p;
    }

    class Person
        def __init__(self, name: str, age: int):
            self.name = name
            self.age = age

You really think that this is not like a C struct because it has too much boilerplate compared to the C equivalent?

Of course it's trivial to wrap up that boilerplate if you're going to create 20 of these. And to add in other functionality that C structs (and, except for the first, Python namedtuples) don't have that your project needs, like a nice repr, default values, runtime type checking, a JSON serialization schema, an ORM mapping, an HTML form representation, etc.

If you really want to add in being a sequence, you can add that too--but again, what's the use case for that? It's certainly not being more like a C struct.



More information about the Python-ideas mailing list