Advanced Python 8 | OOP, Namedtuple, and Dataclass

Series: Advanced Python

Advanced Python 8 | OOP, Namedtuple, and Dataclass

  1. Class and Objects
  • Class name rules

We use the camel rules for Python classes. You can also see the snake case that we commonly used to name variables in Python.

  • build a class
class Dog:
pass
  • create an object
class Dog:
pass
dog = Dog()
  • run the constructor when creating the object: __init__
  • run the destructor when deleting the object: __del__

Output:

Bay is dead.
  • create an instance method: we must have an object (instance), then we can use this method

Output:

Bay is white. 
Bay is dead.

If we haven’t got an instance, we can not directly use this method. Thus, if we try,

Dog.get_color()

Then, we will have an error,

TypeError: get_color() missing 1 required positional argument: 'self'
  • create a class method: the class method can not use the self attributes, however, it can use the class attributes.

Output:

The dog barks Wloof! 
Bay is white.
The dog barks Wloof!
Bay is dead.
  • create a static method: a static method don’t need anything to run (neither cls or self). You can call a static method whenever you want.

Output:

class method ------------------ 
The dog barks Wloof!
static method ------------------ 
Sit!
instance method ---------------- 
Bay is white.
The dog barks Wloof!
Stand!
Bay is dead.
  • inheritance from the Dog class, we can create a Cat class

Output:

class method ------------------
The cats are meowing!

static method ------------------
Roll over!

instance method ----------------
Tom is white.
The cats can't bark!
The cats are meowing!
Stand!
Tom is dead.

Note that a class can have multiple inheritances (actually, as many parents as you like, but this may cause some conflicts in the constructor __init__).

2. Name Tuples and Data Class

To use the namedtuple, we have to import it from collections,

from collections import namedtuple

To use dataclasses, we have to import it from dataclass

from dataclasses import dataclass
  • Create a point namedtuple class with x and y named Point
Point = namedtuple('Point', ['x', 'y'])
  • Create an instance of this Point namedtuple
p = Point(11, 22)
  • get the x from p
p.x
  • get the y from p
p.y
  • replace x in this namedtuple p with 100
p._replace(x=100)
  • change this namedtuple to a dictionary
dict(p._asdict())
  • change a dictionary to a namedtuple
Point(**dict(p._asdict()))
  • Example: create a PS5 namedtuple from a dictionary
PS5 = namedtuple('PS5', ['name', 'price', 'currency', 'quantity'])
item_dict = dict(name="PlayStation 5",
price=499.99,
currency="US dollars",
quantity=None)
PS5(**item_dict)

Output:

PS5(name='PlayStation 5', price=499.99, currency='US dollars', quantity=None)
  • create a PS5 class
class PS5:
name: str
price: float
currency: str="US dollars"
quantity: int=0

We can build this class, however, we can not initialize the name and other stuff by a simple class like this. For example, if we write,

item = PS5(name="PlayStation 5",
price=499.99,
currency="US dollars",
quantity=0)

We will have an error because PS5 class takes no arguments for construction. That’s why we use dataclass.

  • create a PS5 dataclass
@ dataclass
class PS5:
name: str
price: float
currency: str="US dollars"
quantity: int=0

We use dataclass because it saves our time by not building a constructor for a class, which is useful in data analysis process. Then it is okay for us to use,

item = PS5(name="PlayStation 5",
price=499.99,
currency="US dollars",
quantity=0)