An easy way to create Python classes with dataclass
Using the Decorator Pattern
No. 19
Whenever you create a new class, you have to go through the “boilerplate” of setting up the __init__ method and copying some values into the instance variables. For example, in this simple Employee class, you generally would write:
class Employee:
def __init__(self, frname:str, lname:str, idnum:int):
self.frname = frname
self.lname = lname
self.idnum = idnumwhere you declare the arguments to the init method and then copy them into variables for that instance. Well, if this happens pretty much every time you create a class, why not automate it?
This is what the dataclass decorator does for you. If you use this decorator, your code is reduced to:
@dataclass
class Employee:
frname: str
lname: str
idnum: intAnd the init method and the copying is filled in for you. You also need to import the library that contains this function:
from dataclasses import dataclassbut only once per module.
So, when you go to create an instance of Employee, you proceed as usual:
emp = Employee('Sarah', 'Smythe', 123)
print(emp.nameString())and the arguments are in the same order as in the variable list. In fact, IDEs like PyCharm recognize this decorator (which is just a function call under the covers) and pop up the variable list:
Default values in argument lists
In the same way, you can create a class where some of arguments have default values. In Python itself, you could create a class where most of your employees live in, say, Stamford, CT.
class Employee2:
def __init__(self, frname: str, lname: str, idnum: int,
town='Stamford', state = 'CT', zip='06820'):
self.frname = frname
self.lname = lname
self.idnum = idnum
self.town = town
self.state = state
self.zip = zipFor most people, you can create their class instance and leave out those last three values, since they already have default values:
bill = Employee2('Bill', 'Bogus', 456)
print(bill.nameString(), bill.town, bill.zip)But, if you have an outlier employee who lives somewhere else, you can fill in the rest of the arguments:
sandy= Employee2('Sandy', 'Zwyzzo', 123, 'Bridgeport') print(sandy.nameString(), sandy.town, sandy.zip)Note that Sandy’s zipcode will be wrong, though. You can also pick out specific values to change by name, like the zip code in this example:
robert = Employee2('bob', 'simpson', 345, zip= '06840') print(robert.nameString(), robert.zip)Using dataclass with default values
Of course, the dataclass decorator handles default values in the same wayl:
@dataclass
class Employee2:
frname: str
lname: str
idnum: int
town: str = "Stamford"
state: str = 'CT'
zip: str = '06820'And all of the above class instances will work just fine. Doesn’t that make class creation a lot easier?
You can download all code from GitHub under jameswcooper/newsletter.
Subscribe to this newsletter so you don’t miss a single Monday’s issue!


I think this could be clearer, if you explicitly declared the nameString() function inside the class definition, maybe something like
def nameString(self):
return self.frname + " " + self.lname