Classes & Objects

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Classes and Objects

Like many programming languages, Python supports object-oriented programming where classes are templates that define the data and behavior of objects, which are instances of those classes. If you’ve worked with other languages that support OOP, you’ll find Python’s support for it familiar, but you might be surprised by the syntax.

class ChecklistItem:
    """
    Represents an item in a checklist or "to-do" list.

    Checklist items have the following properties:
    - name: Name of the item to display in the list
    - priority: Can be "low", "medium", or "high".
                The default is "medium".
    - checked: Can be True (checked) or False (unchecked).
               The default is False.
    """

    # Class attribute
    PRIORITY_LEVELS = ["low", "medium", "high"]

    def __init__(self, name, checked=False, priority="medium"):
        """Initialize the item."""

        # Instance attributes
        self.name = name
        self.checked = checked
        # To prevent `priority` from being set to anything other
        # than the values defined in PRIORITY_LEVELS, the initializer
        # calls `priority`'s setter method.
        self.set_priority(priority)

    def priority_emoji(self):
        """Return the item's priority as an colored emoji."""
        icons = {
            "low"   : "🟢",
            "medium": "🟨",
            "high"  : "🔴"
        }
        return icons[self.priority]

    def set_priority(self, priority):
        """Setter for item's priority."""

        # Limit `priority` to allowed values
        if priority not in self.PRIORITY_LEVELS:
            raise ValueError("Priority must be 'low', 'medium', or 'high'")

        # If the `priority` instance attribute has not previously been defined, define it.
        # Otherwise, simply update its value
        self.priority = priority

    def __str__(self):
        """Return a user-friendly string representation of the item."""
        if self.checked:
            checkbox = "✅"
        else:
            checkbox = "⬜️"
        return f"{checkbox} {self.name} {self.priority_emoji()}({self.priority})"

    def __repr__(self):
        """Return a developer-facing string representation of the item."""
        return f"name: {self.name} / priority: {self.priority} / checked: \
          {self.checked}"

Defining a Class

Class definitions begin with the class keyword followed by the name of the class. By convention, classes are named using the CapWords or PascalCase convention, where the first letter of every word in the name is capitalized. All indented code under class ChecklistItem: is part of the class.

The Docstring

Like functions, classes can have docstrings, strings that act as documentation, that immediately follow their first line. Also, like functions, you can access the docstring via the class’ __doc__ property. Try it by running this in a code cell: print(ChecklistItem.__doc__).

Class Attributes

Any variable, or in this case, variable being used as a constant, defined inside the class body but outside any method is a class attribute. The value of a class attribute is shared among all class instances.

The __init__() Method

The first method in the class is __init__(), the built-in initializer method for classes. Its name is often pronounced dunder init, and the double underscores surrounding its name indicates that it’s a special method.

Creating a New Instance

Creating a new instance of a class in Python is straightforward:

# Create a new checklist item, using the default
# `priority` and `checked` values
item_1 = ChecklistItem("Clean the kitchen")

# Create another checklist item, but with
# `priority` set to "high" and `checked`
# set to True
item_2 = ChecklistItem("Walk the dog", True, "high")

Instance Attributes

Two of the three instance attributes of ChecklistItem instances are defined in the __init__() method by these lines:

self.name = name
self.checked = checked
self.set_priority(priority)
print(item_1.name)  # Clean the kitchen
item_1.checked = True
item_2.name = "Finish homework"

Defining and Calling Methods

The two methods after the __init__() method are:

print(item_1.priority_emoji())
item_2.set_priority("low")

The __str__() and __repr__() Methods

There are two more methods after priority_emoji() and set_priority(), both of which are “dunder” methods (methods whose names begin and end with double-underscores) that are built into Python classes:

item_3 = ChecklistItem("Do laundry", priority="low")

print("Here's the result of __str__():")
print(item_3)

print("Here's the result of __repr__():")
item_3

Properties

Properties are a special attribute that lets you define behind-the-scenes getter and setter methods that look like directly accessing the attribute. They’re similar to C#’s, Kotlin’s and Swift’s properties, or JavaScript’s get and set methods.

@property
def priority(self):
    return self._priority

@priority.setter
def priority(self, value):
    """Setter for item's priority."""

    # Limit `priority` to allowed values
    if value not in self.PRIORITY_LEVELS:
        raise ValueError("Priority must be 'low', 'medium', or 'high'")

    # If the `_priority` instance attribute has not previously been defined, define it;
    # otherwise, simply update its value
    self._priority = value
def __init__(self, name, checked=False, priority="medium"):
    """Initialize the item."""

    # Instance attributes
    self.name = name
    self.checked = checked
    self.priority = priority # `self.priority` is the property;
                             # `priority` is the parameter.

Inheritance

Like most programming languages that support object-oriented programming, Python supports class inheritance.

import datetime
from datetime import date

class DueDateChecklistItem(ChecklistItem):
    """
    A `ChecklistItem` subclass with a due date and related methods.
    """

    def __init__(self, name, checked=False, priority="medium", due_date=date.today()):
        super().__init__(name, checked, priority)
        self.due_date = due_date

    @property
    def due_date(self):
        return self._due_date

    @due_date.setter
    def due_date(self, value):
        self._due_date = value

    def is_due_today(self):
        """
        An item is due today if:
        - Today is the due date
        - The item is unchecked
        """
        return self.due_date == date.today() and not self.checked

    def is_overdue(self):
        """
        An item is overdue if:
        - Today is past the due date
        - The item is unchecked
        """
        return date.today() > self.due_date and not self.checked

    def priority_emoji(self):
        """
        Return the item's priority as an colored emoji,
        plus an emoji of a "time's up" hourglass
        if the item is overdue.
        """
        icons = {
            "low"   : "🟢",
            "medium": "🟨",
            "high"  : "🔴"
        }
        if self.is_overdue():
            additional_emoji = "⌛️"
        else:
            additional_emoji = ""
        return f"{icons[self.priority]}{additional_emoji}"
item_3 = DueDateChecklistItem("Clean the garage")
print(item_3)
# The result:
⬜️ Clean the garage 🟨(medium)
See forum comments
Download course materials from Github
Previous: Functions: Deep Dive Next: Writing Python Code Demo