[Python-ideas] namedlist() or Record type

anatoly techtonik techtonik at gmail.com
Fri Jul 26 13:30:01 CEST 2013


On Wed, Jul 24, 2013 at 4:28 PM, Eric V. Smith <eric at trueblade.com> wrote:
> On 07/24/2013 08:54 AM, Steven D'Aprano wrote:
>> On 24/07/13 17:50, anatoly techtonik wrote:
>>> Rationale: There are many 2D data with table layout where order is
>>> important and it is hard to work with them in Python.
>> [...]
>>
>> It sounds to me that what you want is a mutable namedtuple. At least,
>> that's what I often want. namedtuple was a fantastically useful addition
>> to the standard library, I think a mutable record type would be too.

Yes, "mutable namedtuple" is the name.

> There are a number of implementations of this on PyPi, and probably
> elsewhere. Here's one I wrote:
>
> https://pypi.python.org/pypi/recordtype/
>
> It could use some polishing. I don't particularly like that it conflates
> mutability along with default parameters, but I couldn't think of an
> easy way to separate them, and for my particular use I needed both.

That was the first idea for me too, but I'd like to see this defined
differently. I remember my confusion when I first met "namedtuple"
factory call in the code, so I'd prefer an easy static approach for
names definition (such as class attribute). Default are not needed for
such "mutable namedtuple", because it should always be initialized
with list of the fixed length.


What does the recordtype module do is helping to build a record given
only partial set of data fields. This use case is often seen in DB
oriented applications (Django models [1], etc.) and if you want a
clear definition of your defaults, IMHO that's a way to go. Other
static definitions I can think about look ugly and not extensible
(i.e. with additional field properties besides defaults):

class TermiosState(DictRecord):
    NAMES = ['iflag', 'oflag', 'cflag', 'lflag', 'ispeed', 'ospeed', 'cc']
    DEFAULTS = [0, 0, 0, 0, 0, 0, 0]

or

class TermiosState(DictRecord):
    NAMES = ['iflag', 'oflag', 'cflag', 'lflag', 'ispeed', 'ospeed', 'cc']
    DEFAULTS = dict(lflag=0)

or

class TermiosState(DictRecord):
    NAMES = dict(
       iflag=0,
       oflag=0,
       ...
    )

I like the definition of macropy "case" classes [2] mentioned by Haoyi
Li. The name is the most unfortunate among all the names I can
remember -  "case" means so many things in English and in programming
in particular, that people new to the concept may hack their brain
before they find an appropriate tutorial. These "case classes" surely
look like a hack, as they redefine the role of class definition
parameters, but they hold more practical value than a multiple
inheritance to me:

@case
class Point(x, y): pass

The TermiosState can then be rewritten as:

@record
class TermiosState(iflag, oflag, cflag, lflag, ispeed, ospeed, cc):
    iflag = 0   # default

Of course this is not as extensible as Django model definition. I am
not sure if such syntax is portable across Python implementations, but
it is the most concise. Of course there should be the proper check for
name typos in section with defaults.

1. https://docs.djangoproject.com/en/dev/topics/db/models/
2. https://github.com/lihaoyi/macropy#case-classes
--
anatoly t.


More information about the Python-ideas mailing list