To create a class variable, annotate the field as a typing.ClassVar or not at all.

from typing import ClassVar
from dataclasses import dataclass

@dataclass
class Foo:
    ivar: float = 0.5
    cvar: ClassVar[float] = 0.5
    nvar = 0.5

foo = Foo()
Foo.ivar, Foo.cvar, Foo.nvar = 1, 1, 1
print(Foo().ivar, Foo().cvar, Foo().nvar)   # 0.5 1 1
print(foo.ivar, foo.cvar, foo.nvar)         # 0.5 1 1
print(Foo(), Foo(12))                       # Foo(ivar=0.5) Foo(ivar=12)

There is a subtle difference in that the unannotated field is completely ignored by @dataclass, whereas the ClassVar field is stored but not converted to an attribute.


dataclasses โ€” Data Classes

The member variables [...] are defined using PEP 526 type annotations.

Class variables

One of two places where dataclass() actually inspects the type of a field is to determine if a field is a class variable as defined in PEP 526. It does this by checking if the type of the field is typing.ClassVar. If a field is a ClassVar, it is excluded from consideration as a field and is ignored by the dataclass mechanisms. Such ClassVar pseudo-fields are not returned by the module-level fields() function.

Answer from user5349916 on Stack Overflow
Top answer
1 of 2
152

To create a class variable, annotate the field as a typing.ClassVar or not at all.

from typing import ClassVar
from dataclasses import dataclass

@dataclass
class Foo:
    ivar: float = 0.5
    cvar: ClassVar[float] = 0.5
    nvar = 0.5

foo = Foo()
Foo.ivar, Foo.cvar, Foo.nvar = 1, 1, 1
print(Foo().ivar, Foo().cvar, Foo().nvar)   # 0.5 1 1
print(foo.ivar, foo.cvar, foo.nvar)         # 0.5 1 1
print(Foo(), Foo(12))                       # Foo(ivar=0.5) Foo(ivar=12)

There is a subtle difference in that the unannotated field is completely ignored by @dataclass, whereas the ClassVar field is stored but not converted to an attribute.


dataclasses โ€” Data Classes

The member variables [...] are defined using PEP 526 type annotations.

Class variables

One of two places where dataclass() actually inspects the type of a field is to determine if a field is a class variable as defined in PEP 526. It does this by checking if the type of the field is typing.ClassVar. If a field is a ClassVar, it is excluded from consideration as a field and is ignored by the dataclass mechanisms. Such ClassVar pseudo-fields are not returned by the module-level fields() function.

2 of 2
10

You should annotate class variable with typing.ClassVar for mypy to capture errors when a class variable is assigned a value via an instance of the class.

Leaving out annotation completely won't help mypy.

from dataclasses import dataclass
from typing import ClassVar


@dataclass
class Class:
    name: ClassVar[str]
    desc = "default description"


instance = Class()
instance.desc = "instance description"
instance.name = "instance name"

Class.name = "class name"
Class.desc = "class description"

Mypy output;

error: Cannot assign to class variable "name" via instance
๐ŸŒ
Python
typing.python.org โ€บ en โ€บ latest โ€บ spec โ€บ dataclasses.html
Dataclasses โ€” typing documentation
@dataclass class Employee: # Field ... a class variable) because type # annotation is not provided. office_number = "unassigned" Libraries that support dataclass-like semantics and support field specifier classes typically use common parameter names to construct these field specifiers. This specification formalizes the names and meanings of the parameters that must be understood for static type ...
๐ŸŒ
Python
docs.python.org โ€บ 3 โ€บ library โ€บ dataclasses.html
dataclasses โ€” Data Classes
Source code: Lib/dataclasses.py This module provides a decorator and functions for automatically adding generated special methods such as__init__() and__repr__() to user-defined classes. It was ori...
๐ŸŒ
GeeksforGeeks
geeksforgeeks.org โ€บ python โ€บ g-fact-34-class-or-static-variables-in-python
Class (Static) and Instance Variables in Python - GeeksforGeeks
Class variables are shared by all objects of a class, whereas instance variables are unique to each object. Unlike languages such as Java or C++, Python does not require a static keyword.
Published: March 6, 2026
๐ŸŒ
Python
peps.python.org โ€บ pep-0557
PEP 557 โ€“ Data Classes - Python Enhancement Proposals
One main design goal of Data Classes is to support static type checkers. The use of PEP 526 syntax is one example of this, but so is the design of the fields() function and the @dataclass decorator.
๐ŸŒ
Reddit
reddit.com โ€บ r/learnpython โ€บ creating class variables in dataclass that are set by a class function?
r/learnpython on Reddit: Creating class variables in dataclass that are set by a class function?
February 25, 2022 -

I have an unusual use case where I have a dataclass with a bunch of attributes. Each attribute optionally contains multiple function pointers using the dataclass.field metadata dictionary.

My main script is iterating over around million data rows, putting the data into this dataclass, and then needs to figure out which function to call for each attribute.

I originally created a class method to return a dictionary of the attributes and their corresponding function. Example code:

@dataclass
def MyClass:
attribute_a: str = field(metadata={
'function_type_1': function_pointer_a,
'function_type_2': function_pointer_b})
attribute_b: str = field(metadata={
'function_type_1': function_pointer_c,
'function_type_2': function_pointer_d})

@classmethod
def get_function_type_1_dictionary(cls) -> dict:
return {class_field.name: function_type_1
for class_field in dataclass.fields(cls)
if (function_type_1 := class_field.metadata.get('function_type_1'))}

This has worked, but I've noticed that it is a little bit slow since the class method is recreating the dictionary from scratch each time.

My idea to speed this up a bit, would be to make a class variable that contains the dictionary, and then create a class method to simply return this dictionary. This way, the dictionary would only be created once.

I know to create a class variable in a dataclass, I create an attribute and give it a typehint of ClassVar, but when I set it equal to a function defined lower in the class, it cannot resolve the reference to the function:

@dataclass
def MyClass:
attribute_a: str = field(metadata={
'function_type_1': function_pointer_a,
'function_type_2': function_pointer_b})
attribute_b: str = field(metadata={
'function_type_1': function_pointer_c,
'function_type_2': function_pointer_d})
my_class_var: ClassVar[dict] = get_function_type_1_dictionary()

Is there a way to accomplish this? Or am I barking up the wrong tree?

๐ŸŒ
Python.org
discuss.python.org โ€บ typing
Static-only `frozen` data classes (or other ways to avoid runtime overhead) - Typing - Discussions on Python.org
February 26, 2024 - Making a Python data class frozen incurs a runtime performance penalty. There is of course an explanation for it, but the overall behaviour is a little counterintuitive โ€“ as a frozen data class can do less than its mutable counterpart.
Find elsewhere
๐ŸŒ
death and gravity
death.andgravity.com โ€บ dataclasses
Dataclasses without type annotations - death and gravity
But if you really want to use dataclasses, you can, static typing or not. Here: >>> @dataclass ... class Data: ... one: ... ... two: ... = 2 ... >>> Data(1) Data(one=1, two=2) I'll say it again: dataclasses do not require type annotations. Despite what most examples show, they only require variable annotations. If you'd like to know why, how to make the best of it, and what this means about Python ...
๐ŸŒ
Bruceeckel
bruceeckel.com โ€บ 2022 โ€บ 05 โ€บ 11 โ€บ misunderstanding-python-class-attributes
Misunderstanding Python Class Attributes
May 11, 2022 - In class B, x is changed to a static variable, which means there is only a single piece of x storage for the classโ€”no matter how many instances of that class you create. This is how Python class attributes work; they are static variables without using the static keyword.
๐ŸŒ
Python.org
discuss.python.org โ€บ typing
Treatment of `Final` attributes in dataclass-likes - Typing - Discussions on Python.org
February 28, 2024 - (redirection from my post at pyright) ... within class body are to be interpreted as: class-level constants, if they have a value assigned, instance-level constants, if the value ......
๐ŸŒ
Medium
medium.com โ€บ @pouyahallaj โ€บ python-data-classes-the-key-to-clean-maintainable-code-a76a740d9884
Python Data Classes: The Key to Clean, Maintainable Code
June 1, 2023 - Type hints in Python provide a way to annotate variables, function parameters, and return values with their expected types. Python data classes seamlessly integrate with type hints, enhancing code clarity, enabling static type checking, and improving maintainability. Letโ€™s explore how type hints can be leveraged with data classes. To annotate fields in a data class, you can simply specify the desired type after the field name. Hereโ€™s an example: from dataclasses import dataclass @dataclass class Point: x: float y: float
๐ŸŒ
CSDN
devpress.csdn.net โ€บ python โ€บ 63045333c67703293080b244.html
Proper way to create class variable in Data Class_python_Mangs-Python
August 23, 2022 - To create a class variable, annotate the field as a typing.ClassVar or not at all. from typing import ClassVar @dataclass class Foo: ivar: float = 0.5 cvar: ClassVar[float] = 0.5 nvar = 0.5 foo = Foo() Foo.ivar, Foo.cvar, Foo.nvar = 1, 1, 1 print(Foo().ivar, Foo().cvar, Foo().nvar) # 0.5 1 1 print(foo.ivar, foo.cvar, foo.nvar) # 0.5 1 1
๐ŸŒ
Medium
medium.com โ€บ @cndro โ€บ class-or-static-variables-in-python-5359b55148bb
Class or Static Variables in Python | Medium
July 19, 2022 - Whenever we have a class, all class objects will share the static variable. This static variables can be accessed either by class name or through object reference such as ClassName.static_variable_name.
๐ŸŒ
FavTutor
favtutor.com โ€บ blogs โ€บ static-variable-python
Static Variable in Python (How to Create and Access it?)
September 12, 2022 - When we want to leave something as a constant, we use the term "static." In Python, 'static' is needed when we want to create any variable or method for the class, i.e. shared by all instances (objects) of the class.
๐ŸŒ
Reddit
reddit.com โ€บ r/askpython โ€บ static typing using `make_dataclass` and `bases`
r/AskPython on Reddit: Static typing using `make_dataclass` and `bases`
August 9, 2022 - One way to do this is to inherit from `DataContainer` and add the `@dataclass` decorator when creating a new concrete class; the static typing works this way.
๐ŸŒ
Florimond Manca
florimond.dev โ€บ en โ€บ posts โ€บ 2018 โ€บ 10 โ€บ reconciling-dataclasses-and-properties-in-python
Reconciling Dataclasses And Properties In Python - Florimond Manca
October 10, 2018 - Why not use this to create an init-only wheels variable and store that in a _wheels field? We just need to give the latter a default (e.g. None) so that it is not required by the constructor: # 2_initvar.py from dataclasses import dataclass, InitVar @dataclass class Vehicle: wheels: InitVar[int] _wheels: int = None # default given => not required in __init__() def __post_init__(self, wheels: int): self._wheels = wheels # wheels @property as before