Why use a classmethod over an Instance method in python

Question:

I have been trying to get my head around classmethods for a while now. I know how they work but I don’t understand why use them or not use them.

For example:

I know i can use an instance method like this:

class MyClass():
    def __init__(self):
        self.name = 'Chris'
        self.age = 27

    def who_are_you(self):
        print('Hello {}, you are {} years old'.format(self.name, self.age))

c = MyClass()
c.who_are_you()

I also know that by using the classmethod I can call the who_are_you() without creating an instance of my class:

class MyClass():
    name = 'Chris'
    age = 27

    @classmethod
    def who_are_you(cls):
        print('Hello {}, you are {} years old'.format(cls.name, cls.age))

MyClass.who_are_you()

I don’t get why you would pick one method over the other

Asked By: Mantis

||

Answers:

In your second example, you’ve hard-coded the name and age into the class. If name and age are indeed properties of the class and not a specific instance of the class, then using a class method makes sense. However, if your class was something like Human of which there are many instances with different names and ages, then it wouldn’t be possible to create a class method to access the unique names and ages of the specific instance. In that case, you would want to use an instance method.

In general:

  • If you want to access a property of a class as a whole, and not the property of a specific instance of that class, use a class method.
  • If you want to access/modify a property associated with a specific instance of the class, then you will want to use an instance method.
Answered By: SPKoder

@classmethod declares that method is static, therefore you could use it without creating new instance of class. One the other hand, in first example you have to create instance before youcould use method.
Static methods are very useful for controllers in MVC pattern, etc, while nonstatic methods are used in models.
More about @classmethod and @staticmethod here
https://stackoverflow.com/a/12179752/5564059

Answered By: Taras Zubrei

Class methods are called when you don’t have, or don’t need, or can’t have, an instance. Sometimes, a class can serve as a singleton when used this way. But probably the most common use of class methods is as a non-standard constructor.

For example, the Python dict class has a non-standard constructor called dict.fromkeys(seq, [value]). Clearly, there can be no instance involved – the whole point is to create an instance. But it’s not the standard __init__() constructor, because it takes data in a slightly different format.

There are similar methods in the standard library: int.from_bytes, bytes.fromhex and bytearray.fromhex() and float.fromhex().

If you think about the Unix standard library, the fdopen function is a similar idea – it constructs a file from a descriptor, instead of a string path. Python’s open() will accept file handles instead of paths, so it doesn’t need a separate constructor. But the concept is more common than you might suspect.

Answered By: aghast

To illustrate SPKoder and aghast‘s answers, let’s make a sensible version of your class called Person. We’ll make __init__ take their name and age, and add an alternate constructor that lets us pass the data in another form — let’s say a dict called deets that may contain various other fields.

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def who_are_you(self):
        print('Hello {}, you are {} years old'.format(self.name, self.age))

    @classmethod
    def from_deets(cls, deets):
        name = deets['name']
        age = deets['age']
        return cls(name, age)

Example usage:

steve = Person('Stephen', 27)
steve.who_are_you()  # -> Hello Stephen, you are 27 years old

mels_deets = {'name': 'Melissa', 'age': 32, 'location': 'Ottawa'}
mel = Person.from_deets(some_deets)
mel.who_are_you()  # Hello Melissa, you are 32 years old
Answered By: wjandrea
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.