Check if a class is a dataclass in Python

Docs import dataclasses dataclasses.is_dataclass(something) As mentioned by @Arne internally it simply checks hasattr(something, ‘__dataclass_fields__’), but I’d recommend to not rely on this attribute and directly use is_dataclass. Why you should not rely on __dataclass_fields__: This attribute is not a public API: it’s not mentioned anywhere in the docs. It’s an implementation detail, and so it’s … Read more

python dataclasses with optional attributes

It’s not possible to use a dataclass to make an attribute that sometimes exists and sometimes doesn’t because the generated __init__, __eq__, __repr__, etc hard-code which attributes they check. However, it is possible to make a dataclass with an optional argument that uses a default value for an attribute (when it’s not provided). from dataclasses … Read more

How can I set an attribute in a frozen dataclass custom __init__ method?

The problem is that the default __init__ implementation uses object.__setattr__() with frozen classes and by providing your own implementation, you have to use it too which would make your code pretty hacky: @dataclass(frozen=True, init=False) class Tricky: thing1: int thing2: str def __init__(self, thing3): object.__setattr__(self, “thing3”, thing3) Unfortunately, python does not provide a way to use … Read more

How can dataclasses be made to work better with __slots__?

2021 UPDATE: direct support for __slots__ is added to python 3.10. I am leaving this answer for posterity and won’t be updating it. The problem is not unique to dataclasses. ANY conflicting class attribute will stomp all over a slot: >>> class Failure: … __slots__ = tuple(“xyz”) … x=1 … Traceback (most recent call last): … Read more

type hint for an instance of a non specific dataclass

Despite its name, dataclasses.dataclass doesn’t expose a class interface. It just allows you to declare a custom class in a convenient way that makes it obvious that it is going to be used as a data container. So, in theory, there is little opportunity to write something that only works on dataclasses, because dataclasses really … Read more

How to make “keyword-only” fields with dataclasses?

Update: coming in Python 3.10, there’s a new dataclasses.KW_ONLY sentinel that works like this: @dataclasses.dataclass class Example: a: int b: int _: dataclasses.KW_ONLY c: int d: int Any fields after the KW_ONLY pseudo-field are keyword-only. There’s also a kw_only parameter to the dataclasses.dataclass decorator, which makes all fields keyword-only: @dataclasses.dataclass(kw_only=True) class Example: a: int b: … Read more

Creating nested dataclass objects in Python

You can use post_init for this from dataclasses import dataclass @dataclass class One: f_one: int f_two: str @dataclass class Two: f_three: str f_four: One def __post_init__(self): self.f_four = One(**self.f_four) data = {‘f_three’: ‘three’, ‘f_four’: {‘f_one’: 1, ‘f_two’: ‘two’}} print(Two(**data)) # Two(f_three=”three”, f_four=One(f_one=1, f_two=’two’))

How to give a Pydantic list field a default value?

For pydantic you can use mutable default value, like: class Foo(BaseModel): defaulted_list_field: List[str] = [] f1, f2 = Foo(), Foo() f1.defaulted_list_field.append(“hey!”) print(f1) # defaulted_list_field=[‘hey!’] print(f2) # defaulted_list_field=[] It will be handled correctly (deep copy) and each model instance will have its own empty list. Pydantic also has default_factory parameter. In the case of an empty … Read more