Static Methods in Python (54/100 Days of Python)
In Python, a static method is a method that belongs to a class rather than an instance of the class. Unlike instance methods, which can access instance variables and attributes, static methods do not have access to the instance or class variables. Instead, they are similar to global functions that are contained within a class’s namespace.
Defining a Static Method in Python
To define a static method in Python, you can use the @staticmethod
decorator before the method definition:
class MyClass:
@staticmethod
def my_static_method(arg1, arg2):
print(f'Static method called with arguments: {arg1} and {arg2}')
In this example, my_static_method
is a static method of the MyClass
class. Note that the @staticmethod
decorator is placed just above the method definition and there is no self
argument passed to the method.
Using a Static Method in Python
You can call a static method of a class without creating an instance of that class:
MyClass.my_static_method(10, 20)
This will call the my_static_method
static method of the MyClass
class with arguments 10 and 20.
Static Methods as Utilities
One common use case for static methods is to define utility functions that are used within a class but do not depend on the state of any particular instance. For example, consider a class that represents a geometric point in two dimensions. We could define a static method to calculate the distance between two points:
class Point:
def __init__(self, x, y):
self.x = x
self.y = y
@staticmethod
def distance(p1, p2):
dx = p1.x - p2.x
dy = p1.y - p2.y
return (dx**2 + dy**2) ** 0.5
Here, the distance
method takes two Point
objects and calculates the Euclidean distance between them.
Factory Methods
Another use case for static methods is to define factory methods that create instances of a class. For example, consider a class that represents a car. We could define a static method to create instances of that class based on the parameters passed to it:
class Animal:
def __init__(self, name):
self.name = name
def speak(self):
pass
@staticmethod
def create_animal(name, animal_type):
if animal_type == 'dog':
return Dog(name)
elif animal_type == 'cat':
return Cat(name)
else:
raise ValueError('Invalid animal type')
class Dog(Animal):
def speak(self):
return 'Woof!'
class Cat(Animal):
def speak(self):
return 'Meow!'
# Create a dog and a cat
my_dog = Animal.create_animal(name='Loby', animal_type='dog') # Create an animal of type dog
my_cat = Animal.create_animal(name='Garfield', animal_type='cat') # Create an animal of type cat
random = Animal.create_animal(name='Random', animal_type='random') # ValueError: Invalid animal type
print(my_dog.speak()) # Woof!
print(my_cat.speak()) # Meow!
In this example, we have a base class Animal
and two subclasses Dog
and Cat
that inherit from it. The Animal
class has a static method create_animal
that takes a name
and an animal_type
as parameters. Depending on the animal_type
parameter, the factory method creates a specific instance of the appropriate subclass and returns it. If an invalid animal_type
is passed, the method raises a ValueError
.
We then create a Dog
instance and a Cat
instance using the create_animal
factory method, and call the speak
method on each instance to make them vocalize their respective sounds.
Keep Class-Level State
In some cases, you may want to define a static variable that is shared among all instances of a class. For example, consider a class that represents a car. We could define a static variable to keep track of the total number of cars:
class Car:
_count = 0
def __init__(self, make, model, year):
self.make = make
self.model = model
self.year = year
Car._count += 1
@staticmethod
def count():
return Car._count
# Create some cars
car1 = Car('Honda', 'Civic', 2020)
car2 = Car('Toyota', 'Camry', 2021)
car3 = Car('Ford', 'F-150', 2019)
# Get the number of cars created
print(Car.count()) # 3
In this example, we have a Car
class with three instance variables make
, model
, and year
, and a class-level variable _count
that keeps track of the number of cars created. The _count
variable is initialized to 0 and is incremented every time a new instance of the Car
class is created in the __init__
method.
The count
method is a static method that returns the _count
variable. Since the _count
variable is at the class level, it can be accessed by the static method even though it doesn't have access to any instance variables.
We then create three instances of the Car
class and get the count of the number of cars created using the count
static method. This demonstrates how class-level state can be used in a static method to keep track of information across all instances of the class.
This can be useful in scenarios where you want to keep track of how many instances of a class have been created or to implement class-level caching or memoization of expensive computations or operations.
What’s next?
- If you found this story valuable, please consider clapping multiple times (this really helps a lot!)
- Hands-on Practice: Free Python Course
- Full series: 100 Days of Python
- Previous topic: Properties in Python
- Next topic: Implementing Custom Decorator Functions