Namedtuples: some unexpected inconveniences
Peter Otten
__peter__ at web.de
Thu Apr 13 03:17:28 EDT 2017
Deborah Swanson wrote:
> Peter Otten wrote, on Wednesday, April 12, 2017 11:35 PM
>>
>> Deborah Swanson wrote:
>>
>> > It's a small point, but I suspect getattr(record, label)
>> would still
>> > fail, even if label's value is 'label' and only 'label', but what's
>> > the point of having a variable if it will only ever have just one
>> > value?
>>
>> You are misunderstanding. Your getattr() call fails because you have
>>
>> label = "label"
>>
>> burried somewhere in your code. As soon as you change that to
>>
>> label = <insert an existing attribute name here>
>>
>> the error will go away.
>
>
> Yes, the error goes away, but now getattr(record, label) is useless for
> processing field names, unless you want to write a line of code for each
> one. (I have 17 field names, and forget about passing label to a
> function.)
No, it's not useless:
>>> from collections import namedtuple
>>> T = namedtuple("T", "foo bar baz")
>>> t = T(1, 2, 3)
>>> for name in t._fields:
... print(name, "=", getattr(t, name))
...
foo = 1
bar = 2
baz = 3
And as a special service here's a mutable datatype with sufficient
namedtuple compatibility to replicate the above snippet:
$ cat namedtuple_replacement.py
def struct(name, wanted_columns):
class Struct:
_fields = __slots__ = wanted_columns.split()
def __init__(self, *args):
names = self.__slots__
if len(args) != len(names):
raise ValueError
for name, value in zip(names, args):
setattr(self, name, value)
@classmethod
def _make(cls, args):
return cls(*args)
def __repr__(self):
names = self.__slots__
return "{}({})".format(
self.__class__.__name__,
", ".join("{}={!r}".format(n, getattr(self, n)) for n in
names)
)
Struct.__name__ = name
return Struct
T = struct("T", "foo bar baz")
t = T(1, 2, 3)
print(t)
for name in t._fields:
print(name, "=", getattr(t, name))
t.bar = 42
print(t)
$ python3 namedtuple_replacement.py
T(foo=1, bar=2, baz=3)
foo = 1
bar = 2
baz = 3
T(foo=1, bar=42, baz=3)
More information about the Python-list
mailing list