Hacker News new | ask | show | jobs
by bjourne 1641 days ago
Costs: Depending on a relatively unknown library. Using arcane class decorators and unusual syntactic constructs: @attr.s and x = attr.ib() (a pun?).

Benefits: Saving at best 10-15 lines of boilerplate per data class. Much less if namedtuple works for you.

If you want to save lines in __init__ you can write "for k, v in locals().items(): setattr(self, k, v)". But you shouldn't.

Edit: Forgot to add to the most important cost: Magic. You don't need to know a lot of Python to understand how the standard self.x = x initialization works. However, you do need to understand a lot of Python internals to grok x = attr.ib().

3 comments

> Depending on a relatively unknown library

attrs is not “relatively unknown” as Python libraries go.

> Using arcane class decorators and unusual syntactic constructs: @attr.s and x = attr.ib() (a pun?).

There have been conventional, SFW aliases for the punny ones for...a long time.

there are newer (since 2020) syntactic constructs that might be more to your liking. take a look at the docs again.

Incidentally, I'd recommend against Named Tuples for non-trivial software. Because they can be indexed by integer and unpacked like tuples, additions of new fields are backwards-incompatible with existing code.

yeah this has bitten me before. combine it with overwriting len for a namedtuple and you have a proper mess
I don't like newfangled syntactic constructs since they hide what is going on. :) The example in the article was a Point3D class and for that namedtuple is a good choice (points should be immutable). It's unlikely that you'd want to add fields without also making other backwards-incompatible changes.
> However, you do need to understand a lot of Python internals to grok x = attr.ib().

No more than with namedtuples (in fact, both use essentially the same magic: code generation and `eval`).