<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Fri, Apr 28, 2017 at 4:55 AM, Tin Tvrtković <span dir="ltr"><<a href="mailto:tinchester@gmail.com" target="_blank">tinchester@gmail.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div><div><div><div><div><div>I'm going to posit we need declarative classes. (This is what a library like attrs provides, basically.) For a class to be declarative, it needs to be possible to inspect the class for its attributes and more.<br></div></div></div></div></div></div></div></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div><div><div><div><br></div>I'm putting forward three examples. These examples are based on attrs since that's what I consider to be the best way of having declarative classes in Python today.<br></div></div></div></div></div></blockquote><div><br></div><div>My favorite example of declarative classes in Python today is Python 3.6.1's typing.NamedTuple:</div><div><br>class Employee(NamedTuple):<br>    """Represents an employee."""<br>    name: str<br>    id: int = 3<br><br></div><div>NamedTuple fixes many of the warts of the original namedtuple:</div><div>1. It supports docstrings out of the box, not requiring a subclass (which require setting __slots__ to get right)</div><div>2. It supports default values.</div><div>3. It has a sane declarative syntax.</div><div>4. It's fields can be type checked.</div><div><br></div><div>What's not to love? There are two valid complaints [1] about namedtuple that still apply:</div><div>1. It's a tuple, which brings along extra baggage (numeric indexing/iteration, comparing equal to tuples, etc.)</div><div>2. It's immutable. Sometimes it's convenient to have a mutable class.</div><div><br></div><div>It seems like a simple solution would be make variants of NamedTuple that solve each of these issues. We might call these collections.Struct and collections.FrozenStruct.</div><div><br></div><div>[1] e.g., see <a href="https://glyph.twistedmatrix.com/2016/08/attrs.html" target="_blank">https://glyph.twistedmatrix.<wbr>com/2016/08/attrs.html</a><br></div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr"><div><div><div><div>Third example: I work at a mobile games company. The backends are Python, the games are written in other languages. The backends and the games share data structures - requests, responses, the save game, game data. I want to have a single source of truth for these structures, so I want to generate classes/structs in other languages from the backend Python classes.<br></div></div></div></div></div></blockquote><div><br></div><div>If you're willing to define these classes outside of Python in a separate file (which is quite reasonable if you need cross-language support), then this is exactly the problem solved by protocol buffers (<a href="https://developers.google.com/protocol-buffers/" target="_blank">https://developers.google.com/<wbr>protocol-buffers/</a>). So I'm not sure we really need this fix in Python.<br></div></div></div></div>