Class Methods in Python

It is possible to define two kinds of methods within a Python class that can be called without an object instance:

  • static methods
  • class methods
class MyClass:
    def instance_method(self):
        return 'instance method called', self

    @classmethod
    def class_method(cls):
        return 'class method called', cls

    @staticmethod
    def static_method():
        return 'static method called'


cls = MyClass()

print(cls.instance_method())

# class methods can be called with or without an instance
print(cls.class_method())
print(MyClass.class_method())

# static methods can be called with or without an instance
print(cls.static_method())
print(MyClass.static_method())

# outputs:

('instance method called', <__main__.MyClass object at 0x7f8acf550490>)
('class method called', <class '__main__.MyClass'>)
('class method called', <class '__main__.MyClass'>)
static method called
static method called

Class methods are typically less commonly used, whereas static method are often used to provide class based services. For example, one of the recommended practices in clean coding is to avoid too many overloaded constructors. The simplest way to achieve that is to provide class factory methods. Factory methods are static methods which accept a number of arguments and return an initialised object instance. They are typically named according to how they initialise the object.

Here’s a very contrived example of how we might implement factory methods in Python:

from collections import namedtuple


class Employee:
    def __init__(self, firstname, lastname, employee_id):
        self.firstname = firstname
        self.lastname = lastname
        self.employee_id = employee_id

    def __str__(self):
        return f'{self.firstname}, {self.lastname}, {self.employee_id}'

    @staticmethod
    def from_employee(e):
        return Employee(e.firstname, e.lastname, e.employee_id)

    @staticmethod
    def from_new_hire(p):
        return Employee(p.given, p.surname, p.hire_id)


NewHire = namedtuple('NewHire', 'given surname hire_id')
hire = NewHire(given='gill', surname='smith', hire_id='1234')

employee = Employee('fred', 'blogs', '789')

bob  = Employee("bob", "jones", "123")
fred = Employee.from_employee(employee)
gill = Employee.from_new_hire(hire)

print(bob)
print(fred)
print(gill)

# outputs:

bob, jones, 123
fred, blogs, 789
gill, smith, 1234

So the three types of methods you can use in Python are:

  • instance methods that modify instance and class state. They accept self as an argument
  • class methods that modify class state, accept a class, and have a @classmethod annotation
  • static that methods cannot modify state, and are annotated with @staticmethod

Here’s an example I modified slightly from the RealPython website, using class methods:

class Pizza:
    _numInstances = 0

    def __init__(self, ingredients):
        Pizza._numInstances += 1
        self.ingredients = ingredients

    def __repr__(self):
        return f'Pizza({self.ingredients})'

    @classmethod
    def margherita(cls):
        return cls(['cheese', 'tomatoes'])

    @classmethod
    def procuitoo(cls):
        return cls(['cheese', 'tomatoes', 'ham', 'mushrooms'])

    @classmethod
    def number_pizzas_made(cls):
        return cls._numInstances


print(Pizza.margherita())
print(Pizza.procuitoo())
print(Pizza.number_pizzas_made())

# outputs:

Pizza(['cheese', 'tomatoes'])
Pizza(['cheese', 'tomatoes', 'ham', 'mushrooms'])
2

Lastly, an example of a simple static method:

import math

class Math:
    @staticmethod
    def circle_area(r):
        return r ** 2 * math.pi


print(Math.circle_area(10))

# outputs:

314.1592653589793

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s