3 ms·
Costs: Depending on a relatively unknown library. Using arcane class decorators and unusual syntactic constructs: @attr.s and x = attr.ib() (a pun?). Benefits:
by bjourne 5y 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().
- ledauphin 5y agothere 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.
- atorodius 5y agoyeah this has bitten me before. combine it with overwriting len for a namedtuple and you have a proper mess
- bjourne 5y agoI 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.
- dragonwriter 5y ago> 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.
- joshuamorton 5y ago> 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`).