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.
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!
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With