What is @classmethod for in python?

Question:

I have the following class and I would like to know what the @classmethod above each method of the class is for.

class User(db.Model):
    name = db.StringProperty(required = True)
    pw_hash = db.StringProperty(required = True)
    email = db.StringProperty()

    @classmethod
    def by_id(cls, uid):
        return User.get_by_id(uid, parent = users_key())

    @classmethod
    def by_name(cls, name):
        u = User.all().filter('name =', name).get()
        return u

    @classmethod
    def register(cls, name, pw, email = None):
        pw_hash = make_pw_hash(name, pw)
        return User(parent = users_key(),
                    name = name,
                    pw_hash = pw_hash,
                    email = email)

    @classmethod
    def login(cls, name, pw):
        u = cls.by_name(name)
        if u and valid_pw(name, pw, u.pw_hash):
            return u

This class is used to create an entity for the App Engine datastore.

Answer:

@classmethod , it will receive the class as the first argument, in case it needs to be used for something. It is usually called cls by convention. In this example all the methods have it def by_name(cls, name): For this purpose, C ++ has the function of overloading, but Python does not, so this is where the classmethod is applied. Bottom line: When this method is called, the class is passed as the first argument instead of the instance of that class (as we normally do with methods). This means that you can use the class and its properties within that method without having to instantiate the class. Example:

 class Clase
    @classmethod
    def metodo2(cls, arg):
        pass

Clase.metodo2("argumento")

A practical example:

from enum import Enum


class Tamano(Enum):  # Una enumeracion es simplemente ponerle nombre a numeros
    normal = 1
    familiar = 2
    xl = 3


class Pizza:
    def __init__(self, precio, tamano, ingredientes):
        self.precio = precio
        self.tamano = tamano
        self.ingredientes = ingredientes

    @classmethod
    def napolitana(cls, tamano):
        precio_napolitana = 8990 * tamano
        ingredientes = ['Queso', 'Oregano', 'Tomate']
        # Instanciamos 'cls' que es la clase Pizza
        return cls(precio_napolitana, tamano, ingredientes)


if __name__ == '__main__':
    # Puedo crear pizzas 'a mano':
    hawaiana = Pizza(9990, Tamano.normal, ['Tomate', 'Jamon', 'Pina'])

    # Creamos una pizza con nuestro metodo de clase
    napolitana = Pizza.napolitana(Tamano.familiar)
Scroll to Top