What is a Classmethod
In Python, classmethod
is a built-in decorator that can be used to define a method that belongs to a class and not to an instance of the class. This means that a classmethod
can be called on the class itself rather than on an instance of the class.
The main purpose of a classmethod
is to allow the class to modify or access its own class-level state. This can be useful for creating alternative constructors for a class, or for implementing factory methods that return instances of the class.
To define a classmethod
, you need to add the @classmethod
decorator before the method definition. The first parameter of the method should be cls
, which refers to the class itself. Here is an example:
class MyClass:
class_variable = 10
@classmethod
def class_method(cls, x):
return cls.class_variable * x
result = MyClass.class_method(5)
print(result) # Output: 50
In this example, class_variable
is a class-level variable that can be accessed and modified by the classmethod class_method()
. The class_method()
takes a parameter x
, multiplies it with class_variable and returns the result.
In summary, classmethod is a powerful tool in Python that allows you to define methods that belong to a class rather than an instance of the class. It is commonly used to create alternative constructors or factory methods, and to modify or access class-level state.
What is a Staticmethod
Python provides the built-in staticmethod
decorator, which allows you to define methods that belong to a class but don't require access to any instance or class-level state. Let's take a look at an example of how to use staticmethod
.
Suppose we have a Person
class that represents a person and we want to define a method that takes in two dates and returns the difference between them in years. This method doesn't need to access any instance or class-level state, so it's a good candidate for a staticmethod
.
import datetime
class Person:
def __init__(self, name, birthdate):
self.name = name
self.birthdate = birthdate
@staticmethod
def calculate_age(birthdate, today):
age = today.year - birthdate.year - ((today.month, today.day) < (birthdate.month, birthdate.day))
return age
person1 = Person("John", datetime.date(1990, 1, 1))
today = datetime.date.today()
age = Person.calculate_age(person1.birthdate, today)
print(f"{person1.name} is {age} years old.")
In this example, we defined a calculate_age
method as a staticmethod
. This method takes in two dates, birthdate
and today
, and calculates the difference between them in years using a simple algorithm.
We then created a Person
object with a name and birthdate and retrieved the current date using the datetime.date.today()
method. We called the calculate_age
method on the Person
class and passed in the birthdate of the Person
object and the current date to get the age in years. Finally, we printed out the name of the person and their age.
By using a staticmethod
, we were able to define a method that belongs to the Person
class but doesn't require access to any instance or class-level state. This makes the code more organized and readable.
Comparison of Classmethod and Staticmethod
While classmethod
and staticmethod
may seem similar at first, there are some key differences between the two.
classmethod
is used when you want a method to operate on the class itself rather than on instances of the class. It takes the class as its first argument, typically called cls. This allows you to access class-level state and create new instances of the class as needed.
On the other hand, staticmethod
is used when you want a method to belong to a class but not to any specific instance of the class. It does not take the class as an argument and does not have access to class-level state. It is often used for utility functions that are related to the class, but do not require access to any instance-level state.
Here is a comparison of the two methods:
-
Signature
classmethod
takes acls
parameter as the first argument, which represents the class itself.staticmethod
does not take any special parameter.
-
Accessing lass-level state
classmethod
can access class-level state via thecls
parameter.staticmethod
cannot access class-level state.
-
Creating new instances
classmethod
can create new instances of the class via thecls
parameter.staticmethod
cannot create new instances of the class.
-
Inheritance
classmethod
is inherited by subclasses and can be overridden.staticmethod
is also inherited by subclasses, but cannot be overridden.
Here's an example to illustrate the differences:
class MyClass:
class_var = "class variable"
def __init__(self, inst_var):
self.inst_var = inst_var
@classmethod
def from_class_method(cls, inst_var):
return cls(inst_var + " (created by classmethod)")
@staticmethod
def from_static_method(inst_var):
return MyClass(inst_var + " (created by staticmethod)")
instance = MyClass("instance variable")
instance2 = MyClass.from_class_method("instance variable")
instance3 = MyClass.from_static_method("instance variable")
print(instance.class_var) # "class variable"
print(instance2.class_var) # "class variable"
print(instance3.class_var) # "class variable"
print(instance.inst_var) # "instance variable"
print(instance2.inst_var) # "instance variable (created by classmethod)"
print(instance3.inst_var) # "instance variable (created by staticmethod)"
In this example, we defined a MyClass
with a class_var
and an inst_var
. We then defined a classmethod
and a staticmethod
that create new instances of the class.
When we call the from_class_method
method, it creates a new instance of the class with the given inst_var
and returns it. When we call the from_static_method
method, it creates a new instance of the class and returns it.
As we can see from the output, both methods can access the class variable, but only the classmethod
can access and create new instances of the class.
References