Best-practices in using Python Classes in Programming

ARSLANOV
2 min readMar 28, 2021

Foreword

Python is an object oriented programming language and almost everything in Python is an object. Python Classes are object constructors and widely used in Python-programming world. In this article, I am going to present you some best-practices in using Python Classes in programming. In particular, you will get to know:

  1. The merits of using Classes instead of dictionary: sometimes it is better to use Classes instead of dictionaries in Python programming. You will get to know about these cases
  2. Decreasing the redundancy of your Classes with “dataclasses” module
  3. Using @property instead of instance variables in Classes

A case where using a Class is better than using dictionaries in Python

Sometimes you may feel that creating Classes is time-consuming as well as complex and therefore, you opt for just creating individual methods and using dictionaries as follows:

from datetime import date
import json
def get_fullname(user):
fullname = f'{user['name']} {user['surname']}'
return fullname
def get_user_age(user):
date_born = user['birthday']
age = date.today().year - date_born.year
return age
def load_user():
with open('./user.json', encoding='utf-8') as file:
return json.load(file)

The above-mentioned example uses “user” dictionary and several methods to get user properties. Is this a proper way? You need to take the user, convert it to the dictionary and take the properties by using individual methods. Can we refactor it and use more Pythonic way? The answer is ‘yes’. Look at the following best-practice:

from datetime import date
import json
from dataclasses import dataclass
@dataclass
class User:
name: str
surname: str
birthday: date
@property
def get_fullname(self):
fullname = f'{self.name} {self.surname}'
return fullname
@property
def get_user_age(self):
date_born = self.birthday
age = date.today().year - date_born.year
return age
def load_user():
with open('./user.json', encoding='utf-8') as file:
return User(**json.load(file))

Using “dataclasses”

Sometimes it is overwhelming to use Class because of the need to define many instance variables as follows:

class User:
def __init__(self, name, surname, birthday, citizenship, address, workplace, job):
self.name = name
self.surname = surname
self.birthday = birthday
self.citizenship = citizenship
self.address = address
self.workplace = workplace
self.job = job

There is not a problem with the above example but redundancy.

We can deal with the above-mentioned redundancy by using “dataclasses”:

from dataclasses import dataclass
from datetime import datetime
@dataclass
class User:
name: str
surname: surname
birthday: birthday
citizenship: citizenship
address: address
workplace: workplace
job: job
@property
def get_fullname(self):
fullname = f'{self.name} {self.surname}'
return fullname

Using @property instead of instance variables

While creating Classes, sometimes, you define instance variables just to use in the methods as below:

form datetime import date@dataclass
class User:
name: str
surname: surname
birthday: date
age: None
def calc_user_age(self):
date_born = self.birthday
self.age = date.today().year - date_born.year
def age_display(self):
return f"I am {self.age} years old."

The main problem with the above example is that if you run “age_display” method before “calc_user_age”, you will get “None”. In other words, you should always remember to run “calc_user_age” before “age_display”.

You can refactor the above written code as follows with @property:

form datetime import date@dataclass
class User:
name: str
surname: surname
birthday: date
@property
def age(self):
date_born = self.birthday
age = date.today().year - date_born.year
return age
def age_display(self):
return f"I am {self.age} years old."

--

--