What is the difference between @classmethod
and a 'classic' method in python,
When should I use the @classmethod
and when should I use a 'classic' method in python.
Is the classmethod must be an method who is referred to the class (I mean it's only a method who handle the class) ?
And I know what is the difference between a @staticmethod and classic method Thx
In Python, the @classmethod decorator is used to declare a method in the class as a class method that can be called using ClassName. MethodName() . The class method can also be called using an object of the class. The @classmethod is an alternative of the classmethod() function.
A variable stored in an instance or class is called an attribute. A function stored in an instance or class is called a method.
The static method does not take any specific parameter. Class method can access and modify the class state. Static Method cannot access or modify the class state. The class method takes the class as parameter to know about the state of that class.
__call__ method is used to use the object as a method. __iter__ method is used to generate generator objects using the object.
Let's assume you have a class Car
which represents the Car
entity within your system.
A classmethod
is a method that works for the class Car
not on one of any of Car
's instances. The first parameter to a function decorated with @classmethod
, usually called cls
, is therefore the class itself. Example:
class Car(object):
colour = 'red'
@classmethod
def blue_cars(cls):
# cls is the Car class
# return all blue cars by looping over cls instances
A function acts on a particular instance of the class; the first parameter usually called self
is the instance itself:
def get_colour(self):
return self.colour
To sum up:
use classmethod
to implement methods that work on a whole class (and not on particular class instances):
Car.blue_cars()
use instance methods to implement methods that work on a particular instance:
my_car = Car(colour='red')
my_car.get_colour() # should return 'red'
If you define a method inside a class, it is handled in a special way: access to it wraps it in a special object which modifies the calling arguments in order to include self
, a reference to the referred object:
class A(object):
def f(self):
pass
a = A()
a.f()
This call to a.f
actually asks f
(via the descriptor protocol) for an object to really return. This object is then called without arguments and deflects the call to the real f
, adding a
in front.
So what a.f()
really does is calling the original f
function with (a)
as arguments.
In order to prevent this, we can wrap the function
@staticmethod
decorator,@classmethod
decorator,@staticmethod
turns it into an object which, when asked, changes the argument-passing behaviour so that it matches the intentions about calling the original f
:
class A(object):
def method(self):
pass
@staticmethod
def stmethod():
pass
@classmethod
def clmethod(cls):
pass
a = A()
a.method() # the "function inside" gets told about a
A.method() # doesn't work because there is no reference to the needed object
a.clmethod() # the "function inside" gets told about a's class, A
A.clmethod() # works as well, because we only need the classgets told about a's class, A
a.stmethod() # the "function inside" gets told nothing about anything
A.stmethod() # works as well
So @classmethod
and @staticmethod
have in common that they "don't care about" the concrete object they were called with; the difference is that @staticmethod
doesn't want to know anything at all about it, while @classmethod
wants to know its class.
So the latter gets the class object the used object is an instance of. Just replace self
with cls
in this case.
Now, when to use what?
Well, that is easy to handle:
self
, you clearly need an instance method.self
, but want to know about its class, use @classmethod
. This may for example be the case with factory methods. datetime.datetime.now()
is such an example: you can call it via its class or via an instance, but it creates a new instance with completely different data. I even used them once for automatically generating subclasses of a given class.self
nor cls
, you use @staticmethod
. This can as well be used for factory methods, if they don't need to care about subclassing.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