Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How is the usage of @classmethod causing difference in outputs?

Tags:

python

I was learning about classes and objects in Python when I came across this dilemma. Below are two cases of the same code, one without @classmethod and the other with @classmethod:

#without @classmethod
>>> class Human:  
...     name = "Rounak"  
...     def change_name(self, new_name):  
...             self.name=new_name  
...   
>>> Human().change_name("Agarwal")  
>>> print(Human().name)  
Rounak  

#with @classmethod
>>> class Human:  
...     name = "Rounak"  
...     @classmethod  
...     def change_name(self, new_name):  
...             self.name=new_name  
...   
>>> Human().change_name("Agarwal") 
>>> print(Human().name)  
Agarwal  

As you can see that when not using @classmethod, the name doesn't change from Rounak to Agarwal. I don't seem to understand how.

I went through the definition of @classmethod in the Python documentation and also went through various questions on Stack Overflow that have detailed explanation about the usage of @classmethod but I still don't understand how it is causing this difference in output. I am new to Python, so if I am missing some fundamental knowledge, please let me know.

like image 915
Rounak Avatar asked Jun 28 '18 18:06

Rounak


2 Answers

Using the classmethod changes the name in the class namespace Human.__dict__, which is different from the instance's namespace Human().__dict__. Class methods are usually implemented using a different variable name than self as the first argument, for this reason:

class Human:  
    name = "Rounak"  

    @classmethod  
    def change_name(cls, new_name):  
         cls.name = new_name  

Note that you are calling Human() again within the print call. Every time you call Human() you are creating a new instance, which has its own namespace!

like image 114
wim Avatar answered Sep 24 '22 00:09

wim


Every time you call Human(), you create a new object. If you were to re-use the first object in the print() statement, you'd see the instance attribute was indeed set to Agarwal.

The call to the classmethod persists across all subsequently created instances, because it's modifying the class attribute.

like image 32
jason.ventresca Avatar answered Sep 20 '22 00:09

jason.ventresca