I am creating a dataclass named TransDate
to validate a date field to be imported from a CSV file.
I am adding some properties to return the year, week, month, day, weekday and quarters and i am also calling a function to validate the date according to 6 format types.
This works fine.
I then create a second class named Transactions
of which one of its attributes is the insDate
.
When I instatiate a TransDate
object the properties are working fine.
When I instatiate a Transaction
object and I want to access the TransDate
properties (tr1.insDate.week or tr1.insDate.qrt or any of its properties) I get the error:
AttributeError: 'str' object has no attribute 'week'.
What am I missing?
I am guessing that the return type of the TransDate
class is of a type datetime
and I am struggling finding a way to over-pass this.
I would much appreciate your help.
from dataclasses import dataclass
from datetime import datetime
@dataclass
class TransDate:
insDate: str
# special method that is called after the object is initialized to perform date validation
def __post_init__(self):
self.validate_date()
# date validation according to 6 date format patterns
def validate_date(self) -> datetime:
patterns = ["%d/%m/%Y", "%d-%m-%Y", "%d.%m.%Y", "%Y/%m/%d", "%Y-%m-%d", "%Y.%m.%d"]
for pattern in patterns:
try:
if valid_date := datetime.strptime(str(self.insDate), pattern):
self.insDate = valid_date.date()
raise ValueError
except ValueError:
pass
def __repr__(self) -> str:
return f"{self.day:02}/{self.month:02}/{self.year}"
@property
def year(self) -> str:
return self.insDate.strftime('%Y')
@property
def month(self) -> str:
return self.insDate.strftime('%m')
@property
def day(self) -> str:
return self.insDate.strftime('%d')
@property
def qrt(self) -> str:
match int(self.month):
case int() as sm if sm in range(1, 4):
return "01"
case int() as sm if sm in range(4, 7):
return "02"
case int() as sm if sm in range(7, 10):
return "03"
case int() as sm if sm in range(10, 13):
return "04"
@property
def weekday(self):
return self.insDate.strftime('%w')
@property
def week(self):
return self.insDate.strftime('%W')
@dataclass
class Transaction:
store: int
insDate: TransDate
weekly_sales: float
d1 = TransDate("10-05-2015")
print(d1)
print(d1.qrt)
print(d1.week)
tr1 = Transaction(store=1, insDate="10-11-2005", weekly_sales=45100.45)
print(type(tr1.insDate)) # output <class 'str'>
print(tr1.insDate.week) # output AttributeError: 'str' object has no attribute 'week'
The problem is solved by changing the Transaction
class as follows:
@dataclass
class Transaction:
store: int
insDate: str
weekly_sales: float
def __post_init__(self):
if self.insDate:
self.insDate = TransDate(self.insDate)