Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Type hint for dataclass attribute which changes type in __post_init__

Which type hint should I give to an attribute which changes type in the __post_init__ method?

In the below example the argument passed to the class instance is of type int. However, it gets converted to type str. What is the correct type hint to show?

from dataclasses import dataclass

@dataclass
class Base:

   apples: int   # Should the type hint be 'int' OR 'int | str'
   
   def __post_init__(self):
      self.apples = str(self.apples)   # Type changes from int to str


b = Base(apples=1)   # Type is initially int

I am reusing the same attribute name here because I would like it show up in the __repr__ of the dataclass.

like image 803
kav Avatar asked Aug 13 '26 09:08

kav


1 Answers

You can take the union of two types:

from typing import Union

@dataclass
class Base:
   apples: Union[int, str]
   
   def __post_init__(self):
      self.apples = str(self.apples)   # Type changes from int to str

But in most cases, this is not a good pattern since it makes typing less useful, and you can do things in some other way.

For example, you might do something like define a string property which is derived from some underlying data:

@dataclass
class Base:
    created_at: datetime
   
    @property
    def created_at_str(self) -> str:
        return self.created_at.strftime("%Y-%m-%d %H:%M:%S")

Edit: Based on your comment, if you want the __init__ method to take a tuple and then convert it to a date attribute in the __post_init__, this might be a case where you want to just define your own __init__ method and do it there rather than relying on the constructor that is autogenerated by the dataclass decorator.

like image 101
Andrew Eckart Avatar answered Aug 16 '26 08:08

Andrew Eckart



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!