On Fri, Apr 28, 2017 at 4:55 AM, Tin Tvrtković <tinchester@gmail.com> wrote:
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.

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.

My favorite example of declarative classes in Python today is Python 3.6.1's typing.NamedTuple:

class Employee(NamedTuple):
    """Represents an employee."""
    name: str
    id: int = 3

NamedTuple fixes many of the warts of the original namedtuple:
1. It supports docstrings out of the box, not requiring a subclass (which require setting __slots__ to get right)
2. It supports default values.
3. It has a sane declarative syntax.
4. It's fields can be type checked.

What's not to love? There are two valid complaints [1] about namedtuple that still apply:
1. It's a tuple, which brings along extra baggage (numeric indexing/iteration, comparing equal to tuples, etc.)
2. It's immutable. Sometimes it's convenient to have a mutable class.

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.

[1] e.g., see https://glyph.twistedmatrix.com/2016/08/attrs.html
 
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.

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 (https://developers.google.com/protocol-buffers/). So I'm not sure we really need this fix in Python.