|
| 1 | +# Overview |
| 2 | + |
| 3 | +In order to fulfill its ambitious goal of bringing back the joy to writing classes, it gives you a class decorator and a way to declaratively define the attributes on that class: |
| 4 | + |
| 5 | +```{include} ../README.md |
| 6 | +:start-after: 'code-begin -->' |
| 7 | +:end-before: '## Project Information' |
| 8 | +``` |
| 9 | + |
| 10 | + |
| 11 | +## Philosophy |
| 12 | + |
| 13 | +**It's about regular classes.** |
| 14 | + |
| 15 | +: *attrs* is for creating well-behaved classes with a type, attributes, methods, and everything that comes with a class. |
| 16 | + It can be used for data-only containers like `namedtuple`s or `types.SimpleNamespace` but they're just a sub-genre of what *attrs* is good for. |
| 17 | + |
| 18 | + |
| 19 | +**The class belongs to the users.** |
| 20 | + |
| 21 | +: You define a class and *attrs* adds static methods to that class based on the attributes you declare. |
| 22 | + The end. |
| 23 | + It doesn't add metaclasses. |
| 24 | + It doesn't add classes you've never heard of to your inheritance tree. |
| 25 | + An *attrs* class in runtime is indistinguishable from a regular class: because it *is* a regular class with a few boilerplate-y methods attached. |
| 26 | + |
| 27 | + |
| 28 | +**Be light on API impact.** |
| 29 | + |
| 30 | +: As convenient as it seems at first, *attrs* will *not* tack on any methods to your classes except for the {term}`dunder ones <dunder methods>`. |
| 31 | + Hence all the useful [tools](helpers) that come with *attrs* live in functions that operate on top of instances. |
| 32 | + Since they take an *attrs* instance as their first argument, you can attach them to your classes with one line of code. |
| 33 | + |
| 34 | + |
| 35 | +**Performance matters.** |
| 36 | + |
| 37 | +: *attrs* runtime impact is very close to zero because all the work is done when the class is defined. |
| 38 | + Once you're instantiating it, *attrs* is out of the picture completely. |
| 39 | + |
| 40 | + |
| 41 | +**No surprises.** |
| 42 | + |
| 43 | +: *attrs* creates classes that arguably work the way a Python beginner would reasonably expect them to work. |
| 44 | + It doesn't try to guess what you mean because explicit is better than implicit. |
| 45 | + It doesn't try to be clever because software shouldn't be clever. |
| 46 | + |
| 47 | +Check out {doc}`how-does-it-work` if you'd like to know how it achieves all of the above. |
| 48 | + |
| 49 | + |
| 50 | +## What *attrs* Is Not |
| 51 | + |
| 52 | +*attrs* does *not* invent some kind of magic system that pulls classes out of its hat using meta classes, runtime introspection, and shaky interdependencies. |
| 53 | + |
| 54 | +All *attrs* does is: |
| 55 | + |
| 56 | +1. Take your declaration, |
| 57 | +2. write {term}`dunder methods` based on that information, |
| 58 | +3. and attach them to your class. |
| 59 | + |
| 60 | +It does *nothing* dynamic at runtime, hence zero runtime overhead. |
| 61 | +It's still *your* class. |
| 62 | +Do with it as you please. |
0 commit comments