Object-Oriented Python

Dr. Chris Gwilliams

gwilliamsc@cardiff.ac.uk

So far, we have been writing blocks of code in functions and running them within scripts.

We call this procedural programming or procedure oriented programming

Python is a multi-paradigm language and it allows you to write other styles in the language.

When we call methods, we are attaching functions to objects. If we create objects in our own code, then we are following Object-oriented programming.

Classes and Objects

These are the two key constructs we use in OOP in Python.

A class is the description of a type.

An object is an instance of that class.

A class has one type but it can have MULTIPLE instances

A class describes a thing, such as a car but the objects are the instances, such as each car in the car park.

Exercise

Give me 3 more examples of classes vs objects

Classes in Python

class Person:
    def __init__(self, name):
        self.name = name

    def say_name(self):
        print("Hi, I am called {}".format(name))

We can create an instance of this person:


In [4]:
class Person:
    def __init__(self, name):
        self.name = name
        
    def say_name(self):
        print("Hi, I am called {}".format(self.name))

jimbob = Person("Jimbob")
jimbob.say_name()


Hi, I am called Jimbob

Notice the use of self, we do not explicitly pass it as an argument but it represents the instance. This brings us back to scope.

What would happen if we did used name instead of self.name in the say_name method?

Variables

Classes have variables attached to them and there are two key types we look at here:

Instance variables

Class variables

Class Variables

Variables that are attached to a class and shared across all instances.

class Person:
    person_count = 0

    def __init__(self):
        Person.person_count += 1

In [1]:
class Person:
    person_count = 0
    
    def __init__(self):
        Person.person_count += 1
        
print(Person.person_count)
p = Person()
print(Person.person_count)


0
1

Instance variables

These are properties of a class that are unique to each instance.

class Vampire:
    def __init__(self, name, age):
        self.name = name
        self.age = age

Exercise

There is a class for connections to a Database with the following variables, which ones would be class and which would be instance?

  • connection_string
  • active_connections
  • port
  • username
  • instance
  • class
  • class or instance
  • class or instance

Exercise

Define a class, which have a class variable and have a same instance variable.

Write a method to return (NOT PRINT) the instance variable.

Create instances of the class and print out both.

Methods

Class vs Static

Static methods are methods that exist without an instance being needed and they utilise what Python calls decorators.


In [2]:
class Person:
    person_count = 0
    
    def __init__(self):
        Person.person_count += 1
        
    @staticmethod
    def eat_food(): #no self passed in here
        print("mmmmm")
        
print(Person.person_count)
p = Person()
print(Person.person_count)


0
1

Exercise

Create a class for a car and create a constructor (__init__) that sets the make, model and engine size.

Add some class variables that are general across all cars.

Create methods to get information about each instance.

Create static methods to do things with the car that would be common across all cars.

This is barely the surface to OO programming. You cover this in detail in the next semester.

Extra Credit - Overriding

When we create a class, we are given built in Python methods to run on it already (such as: print, add, multiply, type etc)

We can override these methods in order to do our own thing when we call it.

Prove it? Use on of your classes from earlier and print it. What is it printing? We can make that more detailed:


In [2]:
class Bella:
    def __init__(self): #here is the constructor being overridden
        pass
    def __str__(self): #called when we call `print` on an object
        return "I want you, and I want you forever. One lifetime is simply not enough for me."
    
b = Bella()
print(b)


I want you, and I want you forever. One lifetime is simply not enough for me.

Extra Credit - Overriding

Create a fraction class that takes a numerator and a denominator. Override the print method.

Done? GREAT, now override the __add__ method to add two fractions together.

The formulae for this is:

a   c   ad+bc
- + - = -----
b   d     bd

That's all, Folks!