Search code examples
pythonclass-variablespython-attrs

attrs and class variables


I really like the way how one can define classes via the attrs library. In particular how the usual syntax of python class variables is hijacked to define instance variables. But is there a way to get class variables with attrs?

If I have the following code

from typing import ClassVar, Final

from attrs import define


@define
class Person:
    name: Final[str]
    age: Final[int]
    goes_to_school: Final[bool]
    my_class_var: ClassVar[str]


p = Person('Bart Simpson', 10, True)

p.my_class_var

it fails with AttributeError: 'Person' object has no attribute 'my_class_var'. And indeed, the attrs API reference says

Attributes annotated as typing.ClassVar, and attributes that are neither annotated nor set to an field() are ignored.


Solution

  • You might install class variable by using mixin class with such variable, simple example

    from attrs import define, field
    
    
    class Mixin:
        my_var = 25
    
    
    @define
    class Person(Mixin):
        name = field()
    
    
    p = Person('Jane')
    print(p.my_var)
    

    gives output

    25
    

    alternatively assign variable after class creation

    from attrs import define, field
    
    
    @define
    class Person:
        name = field()
    
    Person.my_var = 25
    p = Person('Jane')
    print(p.my_var)
    

    gives same output

    (tested using attrs 23.1.0 and Python 3.10.12)