Python Class

Everything in Python is an object. Every object can contain methods and variables (with unique values). Objects are created (often called instantiated) from classes.

Related courses
Python Programming Bootcamp: Go from zero to hero

Class example
Consider the example below:

class Animal:
def __init__(self,name):
self.name = name
 
def walk(self):
print(self.name + ' walks.')
 
duck = Animal('Duck')
duck.walk()

We create one object called ‘duck’ from the class Animal. The class has a method (walk) that can be called on each object. We also have a method called __init__(), this is a method that is always called when a new object is created. The self keyword is required for every method. We set the variables with the class (self.name = ..).

python class
Python class and object drawn using the modeling language UML

Once the object is created, we can call its methods and use its variables indefinitely. Every object of the same class has the same methods, but its variables contents may differ.

A Python program may consists of many classes and objects. To demonstrate that, we create two objects from one class:

class Animal:
def __init__(self,name):
self.name = name
 
def walk(self):
print(self.name + ' walks.')
 
duck = Animal('Duck')
duck.walk()
 
rhino = Animal('African Rhino')
rhino.walk()

Encapsulation

In an object oriented python program, you can restrict access to methods and variables. This can prevent the data from being modified by accident and is known as encapsulation.   Let’s start with an example.

Related Courses:
Python Programming Bootcamp: Go from zero to hero

Private methods

encapsulation
encapsulation. Restricted accesss to methods or variables

We create a class Car which has two methods:  drive() and updateSoftware().  When a car object is created, it will call the private methods __updateSoftware().  

This function cannot be called on the object directly, only from within the class.

#!/usr/bin/env python
 
class Car:
 
def __init__(self):
self.__updateSoftware()
 
def drive(self):
print 'driving'
 
def __updateSoftware(self):
print 'updating software'
 
redcar = Car()
redcar.drive()
#redcar.__updateSoftware()  not accesible from object.

This program will output:

updating software
driving

Encapsulation prevents from accessing accidentally, but not intentionally.

The private attributes and methods are not really hidden, they’re renamed adding “_Car” in the beginning of their name.

The method can actually be called using redcar._Car__updateSoftware()

Private variables

encapsulation-example
Class with private variables

Variables can be private which can be useful on many occasions. A private variable can only be changed within a class method and not outside of the class.

Objects can hold crucial data for your application and you do not want that data to be changeable from anywhere in the code.
An example:

#!/usr/bin/env python
 
class Car:
 
__maxspeed = 0
__name = ""
 
def __init__(self):
self.__maxspeed = 200
self.__name = "Supercar"
 
def drive(self):
print 'driving. maxspeed ' + str(self.__maxspeed)
 
redcar = Car()
redcar.drive()
redcar.__maxspeed = 10  # will not change variable because its private
redcar.drive()

If you want to change the value of a private variable, a setter method is used.  This is simply a method that sets the value of a private variable.

#!/usr/bin/env python
 
class Car:
 
__maxspeed = 0
__name = ""
 
def __init__(self):
self.__maxspeed = 200
self.__name = "Supercar"
 
def drive(self):
print 'driving. maxspeed ' + str(self.__maxspeed)
 
def setMaxSpeed(self,speed):
self.__maxspeed = speed
 
redcar = Car()
redcar.drive()
redcar.setMaxSpeed(320)
redcar.drive()

Why would you create them? Because some of the private values you may want to change after creation of the object while others may not need to be changed at all.

Python Encapsulation

To summarize, in Python there are:

Type Description
public methods Accessible from anywhere
private methods Accessible only in their own class. starts with two underscores
public variables Accessible from anywhere
private variables Accesible only in their own class or by a method if defined. starts with two underscores

Other programming languages have protected class methods too, but Python does not.

Encapsulation gives you more control over the degree of coupling in your code, it allows a class to change its implementation without affecting other parts of the code.

Method overloading

method overloading
Several ways to call a method (method overloading)

In Python you can define a method in such a way that there are multiple ways to call it.

Given a single method or function, we can specify the number of parameters ourself.

Depending on the function definition, it can be called with zero, one, two or more parameters.

This is known as method overloading. Not all programming languages support method overloading, but Python does.

Related course
Python Programming Bootcamp: Go from zero to hero

Method overloading example

We create a class with one method sayHello(). The first parameter of this method is set to None, this gives us the option to call it with or without a parameter.

An object is created based on the class, and we call its method using zero and one parameter.

#!/usr/bin/env python
 
class Human:
 
def sayHello(self, name=None):
 
if name is not None:
print 'Hello ' + name
else:
print 'Hello '
 
# Create instance
obj = Human()
 
# Call the method
obj.sayHello()
 
# Call the method with a parameter
obj.sayHello('Guido')

Output:

Hello
Hello Guido

To clarify method overloading, we can now call the method sayHello() in two ways:

obj.sayHello()
obj.sayHello('Guido')

We created a method that can be called with fewer arguments than it is defined to allow.

We are not limited to two variables, your method could have more variables which are optional.

Inheritance

Classes can inherit functionality of other classes. If an object is created using a class that inherits from a superclass, the object will contain the methods of both the class and the superclass. The same holds true for variables of both the superclass and the class that inherits from the super class.

Python supports inheritance from multiple classes, unlike other popular programming languages.

Related Course:
Python Programming Bootcamp: Go from zero to hero

Intoduction

We define a basic class named User:

class User:
name = ""
 
def __init__(self, name):
self.name = name
 
def printName(self):
print "Name  = " + self.name
 
brian = User("brian")
brian.printName()

This creates one instance called brian which outputs its given name. We create another class called Programmer.

class Programmer(User):
 
def __init__(self, name):
self.name = name
def doPython(self):
print "Programming Python"

This looks very much like a standard class except than User is given in the parameters. This means all functionality of the class User is accessible in the Programmer class.

Inheritance example

Full example of Python inheritance:

class User:
name = ""
 
def __init__(self, name):
self.name = name
 
def printName(self):
print "Name  = " + self.name
 
class Programmer(User):
def __init__(self, name):
self.name = name
 
def doPython(self):
print "Programming Python"
 
brian = User("brian")
brian.printName()
 
diana = Programmer("Diana")
diana.printName()
diana.doPython()

The output:

Name  = brian
Name  = Diana
Programming Python

Brian is an instance of User and can only access the method printName. Diana is an instance of Programmer, a class with inheritance from User, and can access both the methods in Programmer and User.

Polymorphism

Sometimes an object comes in many types or forms. If we have a button, there are many different draw outputs (round button, check button, square button, button with image) but they do share the same logic: onClick().  We access them using the same method . This idea is called Polymorphism.

Polymorphism is based on the greek words Poly (many) and morphism (forms).  We will create a structure that can take or use many forms of objects.

Related Course:
Python Programming Bootcamp: Go from zero to hero

Polymorphism with a function:

We create two classes:  Bear and Dog, both  can make a distinct sound.  We then make two instances and call their action using the same method.

class Bear(object):
def sound(self):
print "Groarrr"
 
class Dog(object):
def sound(self):
print "Woof woof!"
 
def makeSound(animalType):
animalType.sound()
 
bearObj = Bear()
dogObj = Dog()
 
makeSound(bearObj)
makeSound(dogObj)

Output:

Groarrr
Woof woof!

Polymorphism with abstract class (most commonly used)

polymorphism example
Polymorphism visual.
Abstract structure is defined in Document class.

If you create an editor you may not know in advance what type of documents a user will open (pdf format or word format?).  

Wouldn’t it be great to acess them like this,  instead of having 20 types for every document?

for document in documents:
print document.name + ': ' + document.show()

To do so, we create an abstract class called document.  This class does not have any implementation but defines the structure (in form of functions) that all forms must have.   If we define the function show()  then both the PdfDocument and WordDocument must have the show() function. Full code:

class Document:
def __init__(self, name):
self.name = name
 
def show(self):
raise NotImplementedError("Subclass must implement abstract method")
 
class Pdf(Document):
def show(self):
return 'Show pdf contents!'
 
class Word(Document):
def show(self):
return 'Show word contents!'
 
documents = [Pdf('Document1'),
Pdf('Document2'),
Word('Document3')]
 
for document in documents:
print document.name + ': ' + document.show()

Output:

Document1: Show pdf contents!
Document2: Show pdf contents!
Document3: Show word contents!

We have an abstract access point (document) to many types of objects (pdf,word) that follow the same structure.

Polymorphism example

polymorphism-example
Structure in abstract class, implementation in other classes

Another example would be to have an abstract class Car which holds the structure  drive() and stop().  

We define two objects Sportscar and Truck, both are a form of Car. In pseudo code what we will do is:

class Car:
def drive abstract, no implementation.
def stop abstract, no implementation.
 
class Sportscar(Car):
def drive: implementation of sportscar
def stop: implementation of sportscar
 
class Truck(Car):
def drive: implementation of truck
def stop: implementation of truck

Then we can access any type of car and  call the functionality without taking further into account if the form is Sportscar or Truck.  Full code:

class Car:
def __init__(self, name):
self.name = name
 
def drive(self):
raise NotImplementedError("Subclass must implement abstract method")
 
def stop(self):
raise NotImplementedError("Subclass must implement abstract method")
 
class Sportscar(Car):
def drive(self):
return 'Sportscar driving!'
 
def stop(self):
return 'Sportscar braking!'
 
class Truck(Car):
def drive(self):
return 'Truck driving slowly because heavily loaded.'
 
def stop(self):
return 'Truck braking!'
 
cars = [Truck('Bananatruck'),
Truck('Orangetruck'),
Sportscar('Z3')]
 
for car in cars:
print car.name + ': ' + car.drive()

Output:

Bananatruck: Truck driving slowly because heavily loaded.
Orangetruck: Truck driving slowly because heavily loaded.
Z3: Sportscar driving!

Inner classes

An inner class or nested class is a defined entirely within the body of another class. If an object is created using a class, the object inside the root class can be used. A class can have more than one inner classes, but in general inner classes are avoided.

Related Course:
Python Programming Bootcamp: Go from zero to hero

Inner class example

We create a class (Human) with one inner class (Head).
An instance is created that calls a method in the inner class:

#!/usr/bin/env python
 
class Human:
 
def __init__(self):
self.name = 'Guido'
self.head = self.Head()
 
class Head:
def talk(self):
return 'talking...'
 
if __name__ == '__main__':
guido = Human()
print guido.name
print guido.head.talk()

Output:

Guido
talking...

In the program above we have the inner class Head() which has its own method. An inner class can have both methods and variables. In this example the constructor of the class Human (__init__) creates a new head object.  

Multiple inner classes

You are by no means limited to the number of inner classes, for example this code will work too:

#!/usr/bin/env python
 
class Human:
 
def __init__(self):
self.name = 'Guido'
self.head = self.Head()
self.brain = self.Brain()
 
class Head:
def talk(self):
return 'talking...'
 
class Brain:
def think(self):
return 'thinking...'
 
if __name__ == '__main__':
guido = Human()
print guido.name
print guido.head.talk()
print guido.brain.think()

By using inner classes you can make your code even more object orientated. A single object can hold several sub objects.  We can use them to add more structure to our programs.

Posts navigation

1 2 3 4 5 6 7