OOPs in Python

 

Introduction

In Python programming, everything is an object. Variables and even functions are objects. A class is a mold that creates an object.

Think of a popsicle tray. First, you manufacture the popsicle tray to create your desired size, shape, and depth; this is the class. Then, you can decide what to pour into your popsicle tray to freeze — maybe you add water and simply make ice, or maybe you add different kinds of fruit and juices to make popsicles. Each popsicle you create is an object, and objects can have different “data” or flavors associated with them.

This article will demonstrate with code how to create your own class and use it in your Python code. The different components of a class can be broken down into the following: constructors, getters and setters, properties, decorators, privacy naming, class methods, attributes, and inheritance.

When to use a class/object versus a module:

  • Use classes when you need a number of individual instances with similar behavior but different data
  • Use classes when you want support for inheritance; modules do not support inheritance
  • Use a module if you only want one of something
  • Use the simplest solution; modules are usually simpler than classes

Introduction Example of a Class

Below is an example of a simple class. Within the class, we see three components: the __init__ method which is the initialization method, or constructor, a setter method called toss, and a getter method called get_sideup.

How do you use it in your main Python script? In your script, you simply call the object and set it to a new variable. Then you can begin to use its components.

Let’s break it down.

Class Components

Object Initialization Method

When you see a method with the special name __init__, you will know that this is the object initialization method. This is called the constructor because it constructs the object in memory. This method is run automatically when you create an object of your class.

Our __init__ method above requires an argument called name. When we create an object using our Person class, we should pass a name into the call like: Person("Bob").

The self argument specifies that it refers to the individual object itself. Remember that the class is a mold and we can use that mold to initialize (and then later modify) multiple objects. For example, we can create two objects with the Person class:

Getters and Setters

Some object-oriented languages support private object attributes that can’t be accessed directly from the outside. For that reason, you need getter and setter methods to read and write the values of private attributes.

All attributes and methods in Python are public. We don’t need getters and setters. To be “Pythonic”, use properties.

The last line defines the getter and setter methods as properties of the name attribute. Now it will call the getter and setter methods in the following:

Decorators

Decorators are another way to define properties (the same thing we did above).

Privacy Naming

Begin by using two underscores in the name. This makes it so that the attribute can’t be accessed outside of the class definition once you create your object. This also helps to prevent the accidental overriding of attributes by subclasses.

In our Duck class, instead of using hidden_name, use __name.

self.hidden_name = input_name → self.__name = input_name

Class Methods

So far, what we’ve been demonstrating have been instance methods. How can we tell? The first parameter of an instance method is self. When you call an instance method, the call will only affect the copy of the object you are working with.

Class methods affect the class as a whole (and therefore all of its copies of objects). Instead of the self parameter, a class method uses the cls parameter. A class method can be defined by using the class decorator @classmethod

Static methods are a third type of method that affect neither the class nor its objects. It uses no self or cls parameters. It’s just there for convenience.

Attributes

Instance attributes are the outward behaviors we want the object instances to share. A student class may have the attributes:

  • methods: student.get_gpa(), student.add_class(), student.get_schedule()
  • data: student.first_name, student.last_name, student.class_list

dir(object_instance) gives you the list of attributes of that object.

object_instance.__dict__ gives you all the instance attributes specific to that instance (and values)

A class attribute is an attribute of the class, rather than an attribute of an instance of a class. This is an attribute that all objects of the class share together. Let’s say we want to track that every student is a human:

If you want to know more, here is an overly-thorough guide on Python class attributes.

Inheritance

Inheritance allows you to create a hierarchy of classes where a class acquires all the properties and behaviors of a parent class. Then you can make your own specifications on the child class that is different from the parent.

For example, we have a parent class Animal with the ability to eat and sleep. Then we create a child class Cat that also takes on the attributes from Animal, plus its own special attribute.

All you need to do is pass the Animal class into Cat. Now the Cat class has eat() and sleep(). You can override the eat or sleep methods on the Cat subclass by simply defining the method in Cat. You can override any method using __init__().

The child class can add a method that wasn’t in the parent (i.e.; meow()). The parent will not have this method.

Use super() when the child class is doing something on its own but still needs something from the parent:

Benefits of inheritance:

  • Allows subclasses to reuse code from the parent
  • Instead of starting a class from scratch, you can specialize or extend a class
  • The parent class can define an interface to allow subclasses to interact with a program
  • Allows the programmer to organize related objects

Summary

  • A class is a mold (popsicle tray) and an object is created from that class (the popsicle)
  • Objects can call instance methods of their class (using self) to receive and change their data
  • Privacy naming helps to prevent the accidental overriding of attributes by subclasses
  • Classes themselves have methods (using cls) where you can track and manipulate all object instances of that class
  • Inheritance allows us to bring similar classes to scale

Comments

Popular posts from this blog

Flutter for Single-Page Scrollable Websites with Navigator 2.0

A Data Science Portfolio is More Valuable than a Resume

Better File Storage in Oracle Cloud