Indeed! I promise to use dataclass next time I find myself about to use namedtuple. :-)

I'm pretty sure that virtually all my uses will allow that.

On Sat, Jan 26, 2019, 1:09 PM Eric V. Smith <eric@trueblade.com wrote:


On 1/26/2019 12:30 PM, David Mertz wrote:
> On Sat, Jan 26, 2019 at 10:31 AM Steven D'Aprano <steve@pearwood.info
> <mailto:steve@pearwood.info>> wrote:
>
>     In what way is it worse, given that returning a namedtuple with named
>
>     fields is backwards compatible with returning a regular tuple? We can
>     have our cake and eat it too.
>     Unless the caller does a type-check, there is no difference. Sequence
>     unpacking will still work, and namedtuples unlike regular tuples can
>     support optional attributes.
>
>
> I suppose the one difference is where someone improperly relies on tuple
> unpacking.
>
> Old version:
>
>     def myfun():
>          # ...
>          return a, b, c
>
>     # Call site
>     val1, val2, val3 = myfun()
>
>
> New version:
>
>     def myfun():
>          # ...
>          return a, b, c, d
>
>
> Now the call site will get "ValueError: too many values to unpack". 
> Namedtuples don't solve this problem, of course.  But they don't make
> anything worse either.
>
> The better approach, of course, is to document the API as only using
> attribute access, not positional.  I reckon dataclasses from the start
> could address that concern... but so can documentation alone.  E.g.:
>
> Old version (improved):
>
>     def myfun():
>
>          mydata = namedtuple("mydata", "a b c")
>
>          # ...
>          return mydata(a, b, c)
>
>     # Call site
>     ret = myfun()
>
>     val1, val2, val3 = ret.a, ret.b, ret.c
>
>
> New version (improved)
>
>     def myfun():
>
>          mydata = namedtuple("mydata", "a b c d e")
>
>          # ...
>          return mydata(a, b, c, d, e)
>
> Now the call site is completely happy with no changes (assuming it
> doesn't need to care about what values 'ret.d' or 'ret.e' contain... but
> presumably those extra values are optional in some way.
>
> Moreover, we are even perfectly fine if we had created
> namedtuple("mydata", "e d c b a") for some reason, completely changing
> the positions of all the named attributes in the improved namedtuple.

Preventing this automatic unpacking (and preventing iteration in
general) was one of the motivating factors for dataclasses:
https://www.python.org/dev/peps/pep-0557/#id47

Eric