8

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

Derek O
  • 16,770
  • 4
  • 24
  • 43
Mantis
  • 1,357
  • 3
  • 27
  • 49
  • You use an instance method when you have instance variables. With the class method, you can't have different instances with a different age or name – OneCricketeer Feb 28 '16 at 18:31
  • 1
    see: http://stackoverflow.com/questions/12179271/python-classmethod-and-staticmethod-for-beginner – Henry Florence Feb 28 '16 at 18:32
  • 2
    You usually don't create a class to represent a person. Usually, you create a class `Person`, and create instance of it to represent a person. – GingerPlusPlus Feb 28 '16 at 18:32
  • 2
    Possible duplicate of [When should I use @classmethod and when def method(self)?](http://stackoverflow.com/questions/10586787/when-should-i-use-classmethod-and-when-def-methodself) – OneCricketeer Feb 28 '16 at 18:32
  • 2
    Along with what Ginger said, you pass in Chris and 27 into the constructor of the Person class, not hard code them into the class – OneCricketeer Feb 28 '16 at 18:35
  • I had been staring at both those post's for ages and still couldn't figure out why. The way spkoder explained it made sense to me. – Mantis Feb 28 '16 at 18:44

4 Answers4

21

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.
SPKoder
  • 1,835
  • 1
  • 16
  • 19
  • 6
    I have been looking at many examples of classmethod and your explanation was the first that made sense to me. Thank you – Mantis Feb 28 '16 at 18:45
5

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.

aghast
  • 14,785
  • 3
  • 24
  • 56
0

@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

Community
  • 1
  • 1
0

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(mels_deets)
mel.who_are_you()  # Hello Melissa, you are 32 years old
wjandrea
  • 28,235
  • 9
  • 60
  • 81