Package: attrs
attrsis the Python package that will bring back thejoyofwriting classesby relieving you from the drudgery of implementing object protocols (akadunder methods).Trusted by NASAfor Mars missions since 2020!Its main goal is to help you to writeconciseandcorrectsoftware without slowing down your code.Sponsorsattrswould not be possible without ouramazing sponsors.
Especially those generously supporting us at theThe Organizationtier and higher:Please considerjoining themto help makeattrs’s maintenance more sustainable!Exampleattrsgives you a class decorator and a way to declaratively define the attributes on that class:>>>fromattrsimportasdict,define,make_class,Factory>>>@define...classSomeClass:...a_number:int=42...list_of_numbers:list[int]=Factory(list)......defhard_math(self,another_number):...returnself.a_number+sum(self.list_of_numbers)*another_number>>>sc=SomeClass(1,[1,2,3])>>>scSomeClass(a_number=1, list_of_numbers=[1, 2, 3])>>>sc.hard_math(3)19>>>sc==SomeClass(1,[1,2,3])True>>>sc!=SomeClass(2,[3,2,1])True>>>asdict(sc){'a_number': 1, 'list_of_numbers': [1, 2, 3]}>>>SomeClass()SomeClass(a_number=42, list_of_numbers=[])>>>C=make_class("C",["a","b"])>>>C("foo","bar")C(a='foo', b='bar')Afterdeclaringyour attributes,attrsgives you:a concise and explicit overview of the class's attributes,a nice human-readable__repr__,equality-checking methods,an initializer,and much more,withoutwriting dull boilerplate code again and again andwithoutruntime performance penalties.Hate type annotations!?
No problem!
Types are entirelyoptionalwithattrs.
Simply assignattrs.field()to the attributes instead of annotating them with types.This example usesattrs's modern APIs that have been introduced in version 20.1.0, and theattrspackage import name that has been added in version 21.3.0.
The classic APIs (@attr.s,attr.ib, plus their serious-business aliases) and theattrpackage import name will remainindefinitely.Please check outOn The Core API Namesfor a more in-depth explanation.Data ClassesOn the tin,attrsmight remind you ofdataclasses(and indeed,dataclassesare a descendantofattrs).
In practice it does a lot more and is more flexible.
For instance it allows you to definespecial handling of NumPy arrays for equality checks, allows more ways toplug into the initialization process, and allows for stepping through the generated methods using a debugger.For more details, please refer to ourcomparison page.Project InformationChangelogDocumentationPyPISource CodeContributingThird-party ExtensionsGet Help: please use thepython-attrstag onStackOverflowattrsfor EnterpriseAvailable as part of the Tidelift Subscription.The maintainers ofattrsand thousands of other packages are working with Tidelift to deliver commercial support and maintenance for the open source packages you use to build your applications.
Save time, reduce risk, and improve code health, while paying the maintainers of the exact packages you use.Learn more.Release InformationChangesThe type annotation forattrs.resolve_types()is now correct.#1141Type stubs now usetyping.dataclass_transformto decorate dataclass-like decorators, instead of the non-standard__dataclass_transform__special form, which is only supported by Pyright.#1158Fixed serialization of namedtuple fields usingattrs.asdict/astuple()withretain_collection_types=True.#1165attrs.AttrsInstanceis now atyping.Protocolin both type hints and code.
This allows you to subclass it along with anotherProtocol.#1172Ifattrsdetects that__attrs_pre_init__accepts more than justself, it will call it with the same arguments as__init__was called.
This allows you to, for example, pass arguments tosuper().__init__().#1187Slotted classes now transformfunctools.cached_propertydecorated methods to support equivalent semantics.#1200Addedclass_bodyargument toattrs.make_class()to provide additional attributes for newly created classes.
It is, for example, now possible to attach methods.#1203Full changelog