Python Classes & Objects

Anh-Thi Dinh

Classes vs Objects vs Instances vs Methods

  • Class is a blueprint/template of an object.
    • Each class has its own attributes (its states) and methods (its behaviors).
  • Object is a bundle of related attributes and methods.
  • Instance is a single and unique unit of a class.
    • Many instances may have the same class. They have attributes and methods defined in the class.

Syntactic sugar & self

Syntactic sugar is syntax within a programming language that is designed to make things easier to read or to express. For example, we use arr[i,j] but behind the scene, it's get_element(arr, vector(i,j)).
1class MyClass()
2    def method(arg):
3        print(arg)
4
5my_object = MyClass()
6my_object.method('foo')
7# TypeError: method() takes exactly 1 positional argument (2 given)
my_object.method('foo') means MyClass.method(my_object, 'foo'). That's why we need self or a decorator
1class MyClass():
2    def method(self, arg):
3        print(arg)
1# DON'T NEED `self`
2class MyClass():
3    @staticmethod
4    def method(self, arg):
5        print(arg)

Get all attributes of a class

1# CHECK THERE IS AN ATTRIBUTE
2getattr(MyClass, 'report', None)
3# if there is a class, it return this class' detail
4# if not, return None
1def props(cls):
2    return [i for i in cls.__dict__.keys() if i[:1] != '_']
3
4# access these attributes
5properties = props(MyClass)
6for att in properties:
7    print(getattr(MyClass, att))
1# Get dictionaries of all attributes & their values
2MyClass.__dict__

Import local class

Suppose that we have a folders/files structure like below,
1# ORIGINAL STRUCTURE
2popai/
3  processings/
4    a.py # contains class ABC
5    test/
6      b.py
7  lib/
8    c.py # contains class XYZ
1# UPDATED STRUCTURE
2popai/
3  __init__.py
4  processings/
5    __init__.py
6    a.py # contains class ABC
7    test/
8      __init__.py
9      b.py
10  lib/
11    c.py # contains class XYZ
We want import both classes ABC and XYZ
1# b.py
2from popai.processings.a import ABC
1# a.py
2from popai.lib.c import XYZ
Just add __init__.py like in the right box above.
Some errors may occur,
1ValueError: attempted relative import beyond top-level package

Father and Son

1# FATHER
2class father_class():
3  def __init__(self):
4    self.abc = 1
1# SON
2class son_class(father_class):
3  def __init__(self):
4    # son_class has attribute `abc`
5    super().__init__()
6    self.xyz = 2
If you want son takes all parameters of father and use additional parameters,
1class Shape:
2    def __init__(self, shapename):
3        self.shapename = shapename
4
5class ColoredShape(Shape):
6    def __init__(self, color, **kwargs):
7        super().__init__(**kwargs)
8        self.color = color
9
10cs = ColoredShape(color='red', shapename='circle')

Abstract Base Classes (ABC)

1from abc import ABC, abstractmethod
1# FATHER CLASS
2class BaseModel(ABC):
3  def __init__(self):
4    pass
5
6  # child class must have
7  @abstractmethod
8  def fit(self, X):
9    pass
10
11  # child class must have
12  @abstractmethod
13  def predit(self, X):
14    pass
15
16  # children class don't need to have
17  #   but they can call
18  def fit_predict(self, X):
19    pass
1# CHILD CLASS
2class LinearModel(BaseModel)
3  def __init__(self):
4    pass
5
6  # must-have
7  def fit(self, X):
8    pass
9
10  # must-have
11  def predict(self, X):
12    pass
13
14  # this call can use .fix_predict()
15  #   from its father!
16