13

I am writing a function in some class in python, and people suggested to me to add to this function a @classmethod decorator.

My code:

import random


class Randomize:
    RANDOM_CHOICE = 'abcdefg'

    def __init__(self, chars_num):
        self.chars_num = chars_num

    def _randomize(self, random_chars=3):
        return ''.join(random.choice(self.RANDOM_CHOICE)
                       for _ in range(random_chars))

The suggested change:

    @classmethod
    def _randomize(cls, random_chars=3):
        return ''.join(random.choice(cls.RANDOM_CHOICE)
                       for _ in range(random_chars))

I'm almost always using only the _randomize function.

My question is: What is the benefits from adding to a function the classmethod decorator?

Opsy Opsy
  • 185
  • 1
  • 9
  • 7
    It makes it clearer that the method doesn't use any state from the instance, usually named `self`. Also it means you can test it on the class without creating an instance. – jonrsharpe Apr 16 '17 at 12:15
  • Also, if this class doesn't contain much else, it's probably better to use a function and `functools.partial()`. Maybe. – Markus Meskanen Apr 16 '17 at 14:00

1 Answers1

10

If you see _randomize method, you are not using any instance variable (declared in init) in it but it is using a class var i.e. RANDOM_CHOICE = 'abcdefg'.

import random

class Randomize:
    RANDOM_CHOICE = 'abcdefg'

    def __init__(self, chars_num):
        self.chars_num = chars_num

    def _randomize(self, random_chars=3):
        return ''.join(random.choice(self.RANDOM_CHOICE)
                       for _ in range(random_chars))

It means, your method can exist without being an instance method and you can call it directly on class.

  Randomize._randomize()

Now, the question comes does it have any advantages?

  • I guess yes, you don't have to go through creating an instance to use this method which will have an overhead.

    ran = Randomize() // Extra steps
    ran._randomize()   
    

You can read more about class and instance variable here.

Community
  • 1
  • 1
Rahul
  • 2,056
  • 1
  • 21
  • 37
  • I still don't see the point I guess. If you were to have use cases where you want to call that method and don't require an instance of the class, why not have that method live outside that class? – ryanjdillon Nov 07 '18 at 14:31
  • 1
    @ryanjdillon _why not have that method live outside of that class?_ well, that's 'cus the method is well suited in that class but you can also use it in other stuff. Why a `classmethod` instead of a `method` somewhere else? Because it needs parameters from the class, furthermore it doesn't need parameters from the instance. It's useful when you need a resource from a module, but don't want to deal with the "wasted memory(generalization)" that comes with instanciating a class. It's like why you need `staticmethod`? You don't need it per se, but it's tiddier to have related stuff in one place. – dmb Nov 08 '18 at 21:07