Reputation: 707
I'm running Python 3.8.10 and have a dataclass with some attributes. Some of them have a default value but are not part of the constructor.
Attributes which have the init value set to False are not showing up in the object dict.
Is this the expected behavior? How can I force these attributes to show up in vars?
from dataclasses import dataclass, field
@dataclass
class Book:
name: str = field(default="", init=False)
author: str = field(default="", init=True)
b = Book()
b
> Book(name='', author='')
b.name
> ''
b.author
> ''
## name does not show up here
vars(b)
> {'author': ''}
b.__dict__
> {'author': ''}
Upvotes: 2
Views: 6445
Reputation: 371
I just hit the same issue. Some experimenting showed me that these variables show up in vars after they have been set.
I added the following to my __post_init__()
and then they showed up in vars
def __post_init__(self):
for field in dataclasses.fields(self):
#Ensure that all dataclass fields show up in vars
if field.name not in vars(self):
setattr(self, field.name, getattr(self, field.name))
The docs also mention some other weirdness with using init=False. https://docs.python.org/3/library/dataclasses.html#dataclasses.replace
Be forewarned about how init=False fields work during a call to replace(). They are not copied from the source object, but rather are initialized in post_init(), if they’re initialized at all. It is expected that init=False fields will be rarely and judiciously used.
Definitely check your assumptions when it comes to this feature I think.
Upvotes: 2