I have a simple class which I decorate with @dataclass. This class has few properties, but all of them are optional.
@dataclass
class Sample:
field_one: int
field_two: int
...
So far so good. I get the fields parameterized in the __init__ function, however, they are mandatory.
I get the following error if I do not specify them when initializing Sample():
TypeError: __init__() missing 2 required positional arguments: 'field_one', 'field_two'
How can I make all the fields of Sample to be optional and default to None, but without having to specify Optional[type] on each property? I am looking for some kind of "apply-to-all-properties" solution.
This way, I could have the following:
sample = Sample()
print(sample.field_one) # Outputs None
CodePudding user response:
Yes there is a way to do this. However it will mess with your IDE's ability to do autocompletion and wont enforce any constraints that a dataclass is meant to have. So basically overriding alot of dataclass' safety features.
This code will first mark everything as None but will still allow you to pass in kwargs to the init to set as the value.
from dataclasses import dataclass
@dataclass
class Sample:
field_one: int
field_two: int
def __init__(self, **kwargs):
for k in self.__dataclass_fields__:
setattr(self, k, None)
for k, v in kwargs.items():
setattr(self, k, v)
Sample() # Works, everything is None
Sample(field_one=10) # Works, everything is None except for field_one which is now equal to 10
Dry method for this so you don't have to copy and paste everywhere...
Please look at the dataclass decorator and passing init=False
class AllPropertiesAsNone:
def __init__(self, **kwargs):
for k in self.__dataclass_fields__:
setattr(self, k, None)
for k, v in kwargs.items():
setattr(self, k, v)
@dataclass(init=False)
class Sample(AllPropertiesAsNone):
field_one: int
field_two: int
