Python online tutorial

Part 11: Objected-oriented programming

[withcode id="CqA"]

An object-oriented language is one that considers the objects we are handling inside a program with the same importance as the logic connecting them. In object-oriented programming (OOP) language, we can create classes to model real-world objects. We can assign each one a state and a behaviour.

The state of an object is the current situation of the object, and it’s represented by the fields in that object. Each field is a variable (it doesn’t matter which type) at the top of the class. You can have as many fields as you want, including none at all.

The behaviour of an object comprises its input and output mechanisms – usually, it will be implemented using many different functions, which are generally called methods when talking about OOP. Methods are the most common way of interacting with objects and they may or may not change an object’s state.

There is one other component we will definitely need when working with objects: a constructor. Constructors are special functions that return an instance of the object they are in. Instances are specific occurrences of a certain object – you may have two objects of the same type, but each is in a different state – we say these objects have been instantiated from the class where their structure is defined. An object’s constructor is assigned the task of initializing the state of the object, and as we’ll see below the fallback if this fails is controlled by the default state of the object template. A constructor’s first parameter is always “self“. self is a reserved keyword indicating a reference to the current class. If we are in a class instance, then self will refer to that exact instance only.

This might seem vague, but you will understand very quickly with the following example:

Suppose we have been given the task of creating a person in Python. A real person is obviously too complex to represent fully – however, we can create our own simple version, to practice.

We’re going to have only four fields: name, age, gender and hair colour. We will represent name and hair colour as strings, age as an integer and gender as a boolean. This will be the state of our person object.
Let’s think of some relevant methods we can use to model a real person’s behaviour. One obvious choice has to do with the fact that a person’s age usually increases – so how about celebrateBirthday() ? For the example’s sake, one other method may be, say, to dye your hair – dye(colour).

Each object in Python is given a class where it is defined. This class contains all the information about them and their constructor – specific instances of the object will base themselves on this template. Thus, it is generally a good idea to initialize your fields – give them a default behaviour just in case something goes wrong when creating the object. Let’s make a person class:

A lot of stuff is going on in this code snippet. Let’s go through it step by step:

  • class Person is the class definition keyword. As with every code block start in Python, it is suffixed by a colon. We can name the class anything we like, although by convention, class names start with an uppercase letter.
  • name = "unkown"age = 0boy = True and hair_colour = "unknown" are the fields of the Person object. They represent the state of a Person instance. They are initialized to some arbitrary values, but you can change them to whatever you need, add fields, remove fields, etc.
  • def __init__(self, name, age, boy, hair_colour) is the constructor function. Constructors are always called the same: a double underscore, the word init and another double underscore. The first argument is always self. It indicates we want to initialize this object in particular – in fact, in Java this is the keyword which implements the functionality of self. The other parameters of a constructor are usually intended to replace the default fields, but you can, for example, take no extra arguments and just leave the state as is. Inside the function, we are assigning the Person’s fields to the constructor’s arguments – again, notice the self prefix indicates you are referencing the class itself (in other words, these variables are different to the ones passed in).
  • def celebrateBirthday() and def dye(colour) are two methods that represent the behaviour of our Person object. Of course we could create an extensive number of functions if we had more fields, but this is just an example. Caling celebrateBirthday() will increment the age and print a happy birthday message, calling dye() will set the hair_colour field to the colour argument.

Easy! Now, the only thing left is creating an instance of the Person class. Remember we can assign a variable to anything, even an object:

paul = new Person("Paul", 20, True, "blond")

Now, we can just use the name paul to reference our new object. Note the self argument is not required when instantiating a class. To access one of paul‘s fields, we should use the dot operator like so: paul.age. To call a method on paul, use the same thing, but remember you will need to pass all required parameters: paul.dye("red").

One last note: Python’s back-end includes something called “garbage collection“. It will delete inaccessible or unused objects  to free memory periodically, so that the programmer doesn’t have to worry about freeing resources.