Reputation: 93
I have a below NormalClass
that I want to structure as a dataclass
. However I was not sure how I can pass the date_str
param without __init__
in the dataclass
. Any thoughts?
class FieldDateTime():
def __init__(self, data, d_format='%m/%d/%y %I:%M %p'):
try:
self.data = datetime.strptime(data, d_format)
except ValueError as e:
raise ValueError('Dateformat incorrect')
def __call__(self):
return self.data
class NormalClass:
def __init__(self, id, date_str):
self.id: int = id
self.dt: FieldDateTime = FieldDateTime(date_str)
@dataclass
class DataClassObj:
id: int
dt: FieldDateTime(date_str)
How do I pass the date_str as an argument in the data class representation (DataClassObj) without the init?
Upvotes: 9
Views: 14760
Reputation: 16486
Your question has to be more detailed, but I think this is what you're looking for:
from __future__ import annotations
from datetime import datetime
from dataclasses import dataclass, InitVar, field
class FieldDateTime:
def __init__(self, data, d_format='%m/%d/%y %I:%M %p'):
try:
self.data = datetime.strptime(data, d_format)
except ValueError as e:
raise ValueError('Dateformat incorrect')
def __repr__(self):
return f"{self.__class__.__name__}({self.data})"
def __call__(self):
return self.data
@dataclass
class NormalDataClass:
id: int
date_str: InitVar[str]
dt: FieldDateTime = field(init=False)
def __post_init__(self, date_str):
self.dt = FieldDateTime(date_str)
print(NormalDataClass(10, '09/04/21 08:11 PM'))
output (given the dataclass-like __repr__
implementation on FieldDateTime to make it look a bit better):
NormalDataClass(id=10, dt=FieldDateTime(2021-09-04 20:11:00))
Init-only fields are added as parameters to the generated
__init__
method, and are passed to the optional__post_init__
method.
So we can use InitVar
for our date_str
and pass it to __post_init__
to create our FieldDateTime
object.
Upvotes: 10
Reputation: 10736
If i understood you correctly you want to use python dataclasses to achieve default initialization of the class instances fields. This feature is available since Python 3.7 and it implicitly adds __init__
constructor to the class which initializes the class instance with default values you specify.
The code using it would look like below:
from datetime import datetime
class FieldDateTime():
def __init__(self, data, d_format='%m/%d/%y %I:%M %p'):
try:
self.data = datetime.strptime(data, d_format)
except ValueError as e:
raise ValueError('Dateformat incorrect')
def __str__(self):
return str(self.data)
from dataclasses import dataclass
@dataclass
class NormalDataClass:
id: int = 0 # default id
dt: FieldDateTime = FieldDateTime("02/03/20 05:20 AM") # default date
Below code
ndc = NormalDataClass()
print(ndc.id)
print(ndc.dt)
prints:
0
2020-02-03 05:20:00
Upvotes: 2