Imagine you have a function that takes or returns a tuple.
Especially if you use tuple unpacking (eg. ``x, y = get_point()``), adding additional data means that you have to change the invocation of that function *everywhere*.
Adding an attribute to a class concerns only those who actually care about that attribute.
…namedtuples?
-------------
The difference between :func:`collections.namedtuple`\ s and classes decorated by ``attrs`` is that the latter are type-sensitive and less typing aside regular classes:
``characteristic`` is a very similar and fairly popular project of mine.
So why the self-fork?
Basically after nearly a year of usage I ran into annoyances and regretted certain decision I made early-on to make too many people happy.
In the end, *I* wasn't happy using it anymore.
So I learned my lesson and ``attrib`` is the result of that.
Reasons For Forking
^^^^^^^^^^^^^^^^^^^
- Fixing those aforementioned annoyances would introduce more complexity.
More complexity means more bugs.
- Certain unused features make other common features complicated or impossible.
- I want it to be possible to gradually move from ``characteristic`` to ``attrs``.
A peaceful co-existence is much easier if it's separate packages altogether.
- My libraries have very strict backward-compatibility policies and it would take years to get rid of those annoyances while they shape the implementation of other features.
Main Differences
^^^^^^^^^^^^^^^^
- The attributes are defined *within* the class definition such that code analyzers know about their existence.
This is useful in IDEs like PyCharm or linters like PyLint.
- The names are held shorter and easy to both type and read.
- It is generally more opinionated towards typical uses.