# Overview

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:

```{include} ../README.md
:start-after: 'code-begin -->'
:end-before: '### Hate Type Annotations!?'
```


## Philosophy

**It's about regular classes.**

: *attrs* is for creating well-behaved classes with a type, attributes, methods, and everything that comes with a class.
  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.


**The class belongs to the users.**

: You define a class and *attrs* adds static methods to that class based on the attributes you declare.
  The end.
  It doesn't add metaclasses.
  It doesn't add classes you've never heard of to your inheritance tree.
  An *attrs* class in runtime is indistinguishable from a regular class: because it *is* a regular class with a few boilerplate-y methods attached.


**Be light on API impact.**

: 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>`.
  Hence all the useful [tools](helpers) that come with *attrs* live in functions that operate on top of instances.
  Since they take an *attrs* instance as their first argument, you can attach them to your classes with one line of code.


**Performance matters.**

: *attrs* runtime impact is very close to zero because all the work is done when the class is defined.
  Once you're instantiating it, *attrs* is out of the picture completely.


**No surprises.**

: *attrs* creates classes that arguably work the way a Python beginner would reasonably expect them to work.
  It doesn't try to guess what you mean because explicit is better than implicit.
  It doesn't try to be clever because software shouldn't be clever.

Check out {doc}`how-does-it-work` if you'd like to know how it achieves all of the above.


## What *attrs* Is Not

*attrs* does *not* invent some kind of magic system that pulls classes out of its hat using meta classes, runtime introspection, and shaky interdependencies.

All *attrs* does is:

1. Take your declaration,
2. write {term}`dunder methods` based on that information,
3. and attach them to your class.

It does *nothing* dynamic at runtime, hence zero runtime overhead.
It's still *your* class.
Do with it as you please.

---

*attrs* also is *not* a fully-fledged serialization library.
While it comes with features like converters and validators, it is meant to be a kit for building classes that you would write yourself – but with less boilerplate.
If you look for powerful-yet-unintrusive serialization and validation for your *attrs* classes, have a look at our sibling project [*cattrs*](https://catt.rs/) or our [third-party extensions](https://github.com/python-attrs/attrs/wiki/Extensions-to-attrs).

This separation of creating classes and serializing them is a conscious design decision.
We don't think that your business model and your serialization format should be coupled.
