The class method and @classmethod Decorator
A class method is a method that is bound to a class rather than its object. It doesn't require creation of a class instance.The @classmethod decorator exists so you can create class methods that are passed the actual class object within the function call, much like self is passed to any other ordinary instance method in a class.
In those instance methods, the self argument is the class instance object itself, which can then be used to act on instance data. @classmethod methods also have a mandatory first argument, but this argument isn't a class instance, it's actually the uninstantiated class itself.
Let's create @classmethod decorator in our Motorbike class which we have used before. The code is shown below:
class Motorbike():
parking_charges = 100
def __init__(self,name,color,purpose):
self.name=name
self.color=color
self.purpose=purpose
self.charges=700
def bike_description(self):
print("\nYou just got " + self.name + " bike of " + self.color + " color in your garage for " + self.purpose )
def get_amount(self):
print("\nThe minimum servicing charges for the bike is " + str(self.charges))
def billing_amount(self,final_amount):
self.final_amount=final_amount
print("\nThe final servicing charges for the bike is " + str(self.final_amount))
def new_amount(self,final_amount):
self.final_amount+=self.parking_charges
print("\nThe net payable charges for the bike is " + str(self.final_amount))
@classmethod
def change_parking_charges(cls,new_parking_charges):
cls.parking_charges = new_parking_charges
my_bike = Motorbike('Honda','white','servicing')
my_bike.bike_description()
my_bike.get_amount()
my_bike.billing_amount(900)
my_bike.new_amount(900)
Motorbike.change_parking_charges(150)
print("\nNew parking charges changed using @classmethod:\n")
print(my_bike.parking_charges)
In the above shown program the regular method change_parking_charges() has been converted into the class method using the decorator @classmethod at the top.
In the change_parking_charges(cls,amt) method, the first argument cls represents the class. The syntax cls.parking_charges = new_parking_charges sets the parking_charges class variable to the new_parking_charges value, which is passed by the line Motorbike.change_parking_charges(150)
The line Motorbike.change_parking_charges(150) calls the class method change_parking_charges() using the class. We can also use the class instance my_bike to call the class method change_parking_charges() as shown below:
my_bike.change_parking_charges(250)
print("\nNew parking charges changed using instance\n")
print(my_bike.parking_charges)
The output of the program is shown below:
The static method and @staticmethod decorator
The static method doesn't take an instance or class as the first argument. They are just
simple functions. But we include them in class because they have some logical connection
with the class.
Let us consider a situation in our Motorbike class, when any vehicle was parked for more than one day his final bill amount include parking charges else only servicing charges are taken. To turn a regular method into a class method, we will use decorator (@staticmethod) at the top of the method. See the program below:
class Motorbike():
parking_charges = 100
def __init__(self,name,color,purpose):
self.name=name
self.color=color
self.purpose=purpose
self.min_billing_amount=700
@staticmethod
def check_parking_status(parking_amt_payed):
if parking_amt_payed >0:
return True
else:
return False
def billing_amount(self,new_amount,pc):
self.new_amount = new_amount
self.pc = pc
if self.check_parking_status(self.pc):
self.new_amount = self.new_amount + self.pc
return self.new_amount
else:
return self.new_amount
my_bike = Motorbike('Honda','white','servicing')
my_bike1= Motorbike('Enfield','grey','Repairing')
print(my_bike.billing_amount(1000,0))
print(my_bike.billing_amount(1000,200))
In the preceding program, the check_parking_status() method is a static method as specified by the decorator @staticmethod. The check_parking_status() method checks whether amt is greater than 0 or not. The billing_amount() method uses the check_parking_status() static method. The check_parking_status() method does not change the class and instance variable. But it has some logical connection with regular method billing_amount().
The output of the program is shown below:
For Honda bike parking charges are 0 which means vehicle was not parked in the service station hence only servicing charges were taken. For Enfield parking charges are mentioned 200 thus final billing amount is 1200
classmethod VS staticmethod
A class method is a method that is bound to a class rather than its object. It doesn't require creation of a class instance.The @classmethod decorator exists so you can create class methods that are passed the actual class object within the function call, much like self is passed to any other ordinary instance method in a class.
In those instance methods, the self argument is the class instance object itself, which can then be used to act on instance data. @classmethod methods also have a mandatory first argument, but this argument isn't a class instance, it's actually the uninstantiated class itself.
Let's create @classmethod decorator in our Motorbike class which we have used before. The code is shown below:
class Motorbike():
parking_charges = 100
def __init__(self,name,color,purpose):
self.name=name
self.color=color
self.purpose=purpose
self.charges=700
def bike_description(self):
print("\nYou just got " + self.name + " bike of " + self.color + " color in your garage for " + self.purpose )
def get_amount(self):
print("\nThe minimum servicing charges for the bike is " + str(self.charges))
def billing_amount(self,final_amount):
self.final_amount=final_amount
print("\nThe final servicing charges for the bike is " + str(self.final_amount))
def new_amount(self,final_amount):
self.final_amount+=self.parking_charges
print("\nThe net payable charges for the bike is " + str(self.final_amount))
@classmethod
def change_parking_charges(cls,new_parking_charges):
cls.parking_charges = new_parking_charges
my_bike = Motorbike('Honda','white','servicing')
my_bike.bike_description()
my_bike.get_amount()
my_bike.billing_amount(900)
my_bike.new_amount(900)
Motorbike.change_parking_charges(150)
print("\nNew parking charges changed using @classmethod:\n")
print(my_bike.parking_charges)
In the above shown program the regular method change_parking_charges() has been converted into the class method using the decorator @classmethod at the top.
In the change_parking_charges(cls,amt) method, the first argument cls represents the class. The syntax cls.parking_charges = new_parking_charges sets the parking_charges class variable to the new_parking_charges value, which is passed by the line Motorbike.change_parking_charges(150)
The line Motorbike.change_parking_charges(150) calls the class method change_parking_charges() using the class. We can also use the class instance my_bike to call the class method change_parking_charges() as shown below:
my_bike.change_parking_charges(250)
print("\nNew parking charges changed using instance\n")
print(my_bike.parking_charges)
The output of the program is shown below:
The static method and @staticmethod decorator
The static method doesn't take an instance or class as the first argument. They are just
simple functions. But we include them in class because they have some logical connection
with the class.
Let us consider a situation in our Motorbike class, when any vehicle was parked for more than one day his final bill amount include parking charges else only servicing charges are taken. To turn a regular method into a class method, we will use decorator (@staticmethod) at the top of the method. See the program below:
class Motorbike():
parking_charges = 100
def __init__(self,name,color,purpose):
self.name=name
self.color=color
self.purpose=purpose
self.min_billing_amount=700
@staticmethod
def check_parking_status(parking_amt_payed):
if parking_amt_payed >0:
return True
else:
return False
def billing_amount(self,new_amount,pc):
self.new_amount = new_amount
self.pc = pc
if self.check_parking_status(self.pc):
self.new_amount = self.new_amount + self.pc
return self.new_amount
else:
return self.new_amount
my_bike = Motorbike('Honda','white','servicing')
my_bike1= Motorbike('Enfield','grey','Repairing')
print(my_bike.billing_amount(1000,0))
print(my_bike.billing_amount(1000,200))
In the preceding program, the check_parking_status() method is a static method as specified by the decorator @staticmethod. The check_parking_status() method checks whether amt is greater than 0 or not. The billing_amount() method uses the check_parking_status() static method. The check_parking_status() method does not change the class and instance variable. But it has some logical connection with regular method billing_amount().
The output of the program is shown below:
For Honda bike parking charges are 0 which means vehicle was not parked in the service station hence only servicing charges were taken. For Enfield parking charges are mentioned 200 thus final billing amount is 1200
classmethod VS staticmethod
- A class method takes cls as first parameter while a static method needs no specific parameters.
- A class method can access or modify class state while a static method can’t access or modify it.
- In general, static methods know nothing about class state. They are utility type methods that take some parameters and work upon those parameters. On the other hand class methods must have class as parameter.
- We use @classmethod decorator in python to create a class method and we use @staticmethod decorator to create a static method in python.
When to use what?
We generally use class method to create factory methods. Factory methods return class object ( similar to a constructor ) for different use cases.
We generally use static methods to create utility functions.
It is advisable to make some of your own class methods and static methods as the concept is not straight forward and requires some practice. In the next post we'll learn about private variable in Python. Till then keep learning Python as Python is easy to learn!
0 comments:
Post a Comment