Python Basic Series: Classes

Created by Junchao

About me

  • Junchao || Franklin
  • Just graduated from NUS Computer Engineering
  • Software developer || data engineer @ Hedge fund
  • Works with Python everyday

Python

    Beautiful is better than ugly.
    Explicit is better than implicit.
    Simple is better than complex.
    Complex is better than complicated.
    Flat is better than nested.
    Sparse is better than dense.
    Readability counts.
    Special cases aren't special enough to break the rules.
    Although practicality beats purity.
    Errors should never pass silently.
    Unless explicitly silenced.
    In the face of ambiguity, refuse the temptation to guess.
    There should be one-- and preferably only one --obvious way to do it.
    Although that way may not be obvious at first unless you're Dutch.
    Now is better than never.
    Although never is often better than *right* now.
    If the implementation is hard to explain, it's a bad idea.
    If the implementation is easy to explain, it may be a good idea.
    Namespaces are one honking great idea -- let's do more of those!
  

Today's speech's outline

  • Review of previous lecture
  • Overview of Programming Paradigms
  • Classes & Object Oriented
  • More OOP
  • Diagrams


With reference to Standford Python Lecture Notes on Classes, Learn Python the Hard Way, Think Python
All code snippets can be found here

Review of previous lecture

  • Data structure

    • Numbers
    • Strings
    • Booleans
    • Tuples
    • Lists
    • Dictionaries

Review of previous lecture

  • Control statements

    • if-elif-else
    • for
    • while
    • try-except-finally

Review of previous lecture

  • Function

    • use "def"
    • arguments || parameters
    • return values
    • side effects

Review of previous lecture

  • Python import system
  • built-in libraries

Review of previous lecture

  • working with data structures and functions mostly
  • with focus on the procedures of getting things done
  • procedural programming

Programming Paradigms

  • Procedural
  • Functional
  • Object oriented
  • a complete list Wikipedia

Examples

  • C, Shell are Procedural
  • Haskell, Lisp are Functional
  • Java, SmallTalk are Object Oriented
  • Python, C++, OCamel, Swift, Scala are Multi-Paradigms

Python -- Multi-Paradigms

  • For many data science and system administration work: procedural
  • For complicated data structure: class based object oriented
  • For some computation work and decorator: functional
  • Functional: great for tricks and hacks, not largely supported

Python -- Multi-Paradigms

  • For most of time, can do fine with rich built-in data structures and procedural
  • Classes for complicated data and their behavior
  • Functional at times to quickly getting things done

Classes

  • New Syntax
  • Classes & objects
  • Methods vs functions
  • Instance methods vs class methods vs static methods

Why have OOP anyway?

  • Just like procedural or functional
  • To solve certain sorts of problems with ease
  • Model objects in the real world to solve problems

Link to real world

  • We are surrounded by objects: a computer, a desk, a pen, a pretty girl
  • e.g.: that Mac computer and my PC are computers.
  • so many objects are of the same category
  • we call them a class of objects

Link to real world

  • Class: abstract notion of a category of objects
  • Object: some concrete stuff, an instance of a class
  • Pet is a class, and your lovely cat in your home is an object
  • So this is class vs object

Link to real world

  • Pet is a class, and Cat is a sub-class of Pet(loosely)
  • So an object of Cat can be called as a Pet
  • An object of Pet can be a Dog, not Cat, maybe
  • So this is subclassing(Do not worry, we get back to this, hopefully)

Define a class

      
"""Example for defining first class in Python
"""

class FirstClass:
    """Our first class: just a simple demo

    A class is a namespace by itself. When seeing the class keyword,
    a class definition begins. And when the indentation ends, the class
    definition ends and a class object is created.
    So a new class is an object--similar to Ruby and you can create a
    class from metaclass just like you are about to create an object
    from a class. This sounds confusing? Just bear with me for a while.
    """
    pass
      
    

A bit too much--some explanation now

  • A namespace is just a box. Many names are in it.
  • Names in a namespace are not visible to outside of the box
  • A class is a namespace--therefore you cannot see names inside it
  • But of course you may refer to names inside it by referring to the box first

Class as a Namespace

      
"""Explaining class-as-a-namespace notion
"""

class ClassAsANamespace:
    """Demo class-as-a-namespace
    """
    name1 = 'Hello, World!'
    name2 = 1
    name3 = [1, 2, 3]
    name4 = {
        'test': 'Hello, World!'
    }

# You cannot use the statement below, as name1 is inside
#   ClassAsANamespace's namespace. Uncomment it and see it running
# print(name1)

print(ClassAsANamespace.name1)
print(ClassAsANamespace.name2)
print(ClassAsANamespace.name3)
print(ClassAsANamespace.name4)
      
    

class & object

  • A class is an object
  • An object can be created from a class
  • Object is instantiation of a class
  • What is class of an class?
  • metaclass--type
  • But you can let go of type and metaclass for the moment
  • -- advanced topics

Wow, a lot of notions! Take a short rest

  • We know how to define a class now--that is it
  • We know class is a namespace
  • Well, leave other notions to later

Let's create objects now!

      
"""Creation of objects, name it as create_objects.py
"""
class DemoClass:
    """A demo class for object creation
    """
    def __init__(self, a, b, c):
        self.a = a
        self.b = b
        self.c = c

    def a_method(self):
        return self.a

    def another_method(self, b):
        # notice that here self.b could be different from b. this is because of
        # namespace--still remember what is namespace right?--a box full of
        # names inside
        print('Inside self, the b is ', self.b)
        print('The parameter b is ', b)
        return self.c + b


a_obj = DemoClass(1, 2, 3)
print('The type of a_obj is ', type(a_obj))
print('The type of a_obj\'s method is ', type(a_obj.a_method))
print('The return value of a_obj.a_method is ', a_obj.a_method())
print('The return value of a_obj.another_method is ', a_obj.another_method(0))
      
    

More objects' creation

      
"""More examples on objects creation, same folder as create_objects.py
"""
from create_objects import DemoClass

obj1 = DemoClass(1, 2, 'Hello')
print('obj1\'s b is ', obj1.b)
print(
   'Call obj1.another_method for first time: ',
    obj1.another_method(' world!')
)
obj1.c = 'I just said "Hello'
print(
   'Call obj1.another_method after assignment: ',
    obj1.another_method(' world!"')
)
      
    

Methods vs functions

  • method is for objects
  • obj.method(args) == function(current_obj, args)
  • So a method is just a function bound to an object

Practical example of classes & objects

      
"""Practical examples of classes and objects

Pet is a class: representing the abstraction notion of those lovely animations
that keep us company.
"""
class Pet:
    """A example class to represent pets in real life.

    Of course we will not be able to describe every aspect of pets. Just
    an example.
    """
    healthy_weight_range = (1.5, 4.5)
    favorite_foods = ['meat']

    def __init__(self, name, age, weight, color):
        """Instantiation method for a pet.
        """
        self.name = name
        self.age = age
        self.weight = weight
        self.color = color

    def have_birthday(self):
        self.age += 1

    def eat_stuff(self, food):
        if food in self.favorite_foods:
            self.weight += 2
        else:
            self.weight += 0.5

    def exercise(self):
        self.weight -= 0.5

    def check_weight(self):
        if self.__is_weight_healthy():
            return False
        else:
            self.send_weight_warning()
            return True

    def speak(self):
        return '{} says love you'.format(self.name)

    def send_weight_warning(self):
        print('Oh, pleas e take note of my weight')

    def __is_weight_healthy(self):
        lower, upper = self.healthy_weight_range
        if lower <= self.weight and self.weight <= upper:
            return True
        else:
            return False

    def __repr__(self):
        return self.name


if __name__ == '__main__':
    print('Let\'s create some pets')
    print('first have a dog')
    dog1 = Pet('a little dog', 1, 1.5, 'Black and white')
    for _ in range(5):
        dog1.eat_stuff('meat')
    while not dog1.check_weight():
        dog1.exercise()
    print(dog1.speak() + '\n')
    print('then a cat')
    cat1 = Pet('a lovely cat', 2, 1.0, 'Black and white')
    cat1.have_birthday()
    print('Now {} is turning into {} years old!'.format(repr(cat1), cat1.age))
    print(cat1.speak())

      
    

Instance methods vs class methods vs static methods

  • Instance method: methods bound to an instance
  • Class method: methods bound to a class
  • Static method: methods bound to nothing in particular

Instance methods vs class methods vs static methods

      
"""Demostration of instance methods, class methods and static methods
"""
class MethodsDemoClass:
    """Just to demo use of instance methods, class methods and static methods
    """
    var = 'cls'

    def __init__(self, var):
        self.var = var

    def instance_method(self):
        return self.var

    @classmethod
    def class_method(cls):
        return cls.var

    @staticmethod
    def static_method(var):
        return var


obj = MethodsDemoClass('object')
print('Calling instance method: ', obj.instance_method())
print('Calling class method: ', MethodsDemoClass.class_method())
print('Calling static method: ', MethodsDemoClass.static_method('static'))
      
    

More OOP

  • Inheritance
  • Polymorphism
  • Multiple inheritance

Inheritance

  • Subclassing
  • If classA is a subclass of classBase, then any object of classA is a classBase as well
  • iPhone is subclass of SmartPhone--your phone is iPhone, and it is definitely a SmartPhone

Polymorphism

  • Override parent's behavior
  • classA is a subclass of classBase, but for some special behavior it could be special
  • OLevelTest is a Test, SAT is also a Test. OLevelTest has its own rules and so does SAT

Multiple inheritance

  • Can have multiple parents
  • iPhone is a Phone, an iPod and an iTouch

Example

      
"""Demostration of different notions in advanced object oriented programming
"""
from practical_class_object import Pet


class Dog(Pet):
    favorite_foods = ['meat', 'bone']

    def speak(self):
        return 'woof-woof, {} says love you'.format(self.name)


class Cat(Pet):
    favorite_foods = ['meat', 'fish']

    def speak(self):
        return 'meow-meow, {} says love you'.format(self.name)


class DangerousPet:
    def speak(self):
        return 'I am just dangerous'

    def is_angry(self):
        print('Warning!!! Be careful and try not to further piss it off')


class Cheetah(DangerousPet, Pet):
    healthy_weight_range = (25, 45)


if __name__ == '__main__':
    print('Let\'s create some pets')
    print('first have a dog')
    dog1 = Dog('a little dog', 1, 1.5, 'Black and white')
    for _ in range(5):
        dog1.eat_stuff('bone')
    while not dog1.check_weight():
        dog1.exercise()
    print(dog1.speak() + '\n')
    print('then a cat')
    cat1 = Cat('a lovely cat', 2, 1.0, 'Black and white')
    cat1.have_birthday()
    for _ in range(5):
        cat1.eat_stuff('bone')
    print('Now {} is turning into {} years old!'.format(repr(cat1), cat1.age))
    print(cat1.speak() + '\n')
    print('and a cheetah')
    the_cheetah = Cheetah('Handsome and dangerous cheetah', 5, 30, 'yellow and black')
    print(the_cheetah.speak())
    the_cheetah.is_angry()
      
    

Diagrams

  • Use case diagrams
  • Class diagrams

Use case diagrams

A use case diagram at its simplest is a representation of a user's interaction with the system that shows the relationship between the user and the different use cases in which the user is involved.
from Wikipedia

Use case diagrams

from [sourcemaking.com]

Class diagrams

In software engineering, a class diagram in the Unified Modeling Language (UML) is a type of static structure diagram that describes the structure of a system by showing the system's classes, their attributes, operations (or methods), and the relationships among objects.A use case diagram at its simplest is a representation of a user's interaction with the system that shows the relationship between the user and the different use cases in which the user is involved.
from Wikipedia

Class diagrams

from [tutorialspoint.com]

Summary of what has been covered

  • Review of previous lecture
  • Overview of Programming Paradigms
  • Classes & Object Oriented
  • More OOP
  • Diagrams

Thank you