Menu
CoddyTech

Métodos estáticos y de clase

Parte de la sección Programación orientada a objetos del Journey de Python de Coddy. Lección 39 de 64.

Además de los métodos de instancia habituales, las clases pueden tener métodos estáticos y métodos de clase que cumplen distintas funciones.

Aquí tienes un ejemplo de un método estático:

class MathHelper:
    @staticmethod
    def add(a, b):
        return a + b
    
    @staticmethod
    def is_even(number):
        return number % 2 == 0

Los métodos estáticos no necesitan self y funcionan como funciones normales. Llámalos directamente desde la clase:

result = MathHelper.add(5, 3)
print(result)

check = MathHelper.is_even(10)
print(check)

Aquí tienes un ejemplo de un método de clase:

class Person:
    count = 0  # Variable de clase
    
    def __init__(self, name):
        self.name = name
        Person.count += 1
    
    @classmethod
    def get_count(cls):
        return cls.count
    
    @classmethod
    def create_anonymous(cls):
        return cls("Anonymous")

Los métodos de clase reciben la propia clase (cls) como primer parámetro:

person1 = Person("Alice")
person2 = Person("Bob")
print(Person.get_count())  # 2

Usa métodos de clase como constructores alternativos:

anonymous = Person.create_anonymous()
print(anonymous.name)      # Anonymous
print(Person.get_count())  # 3

Compara los tres tipos de métodos en una sola clase:

class Calculator:
    brand = "Python Calc"
    
    def __init__(self, owner):
        self.owner = owner
    
    # Método de instancia - necesita self y accede a los datos de la instancia
    def show_owner(self):
        return f"Owned by {self.owner}"
    
    # Método de clase - necesita cls y accede a los datos de la clase
    @classmethod
    def get_brand(cls):
        return cls.brand
    
    # Método estático - no necesita ninguno de los dos; es solo una función auxiliar
    @staticmethod
    def multiply(x, y):
        return x * y
calc = Calculator("Alice")
print(calc.show_owner())        # Propiedad de Alice
print(Calculator.get_brand())   # Python Calc
print(Calculator.multiply(4, 5)) # 20

Salida:

8
True
2
Anonymous
3
Owned by Alice
Python Calc
20

También puedes llamar a métodos de clase y estáticos desde instancias:

calc = Calculator("Bob")
print(calc.get_brand())      # Python Calc
print(calc.multiply(2, 3))   # 6

Diferencias clave:

  • Métodos de instancia: Necesitan self y acceden a los datos de la instancia
  • Métodos de clase: Necesitan cls, acceden a los datos de la clase y son útiles para constructores alternativos
  • Métodos estáticos: No necesitan ninguno de los dos; son simplemente funciones de utilidad relacionadas con la clase

Punto clave: Usa @staticmethod para funciones auxiliares que pertenecen lógicamente a la clase, pero no necesitan datos de la clase ni de la instancia. Usa @classmethod cuando necesites acceder a la propia clase, por ejemplo, para constructores alternativos o para acceder a variables de clase.

challenge icon

Desafío

Fácil

En este desafío, implementarás una clase Temperature con funcionalidades específicas y aprovecharás un marco de pruebas completo.

Debes editar solo el archivo temperature.py, siguiendo los comentarios TODO que guían tu implementación. La clase debe incluir:

  • Una variable de clase para llevar un registro de las lecturas de temperatura
  • Un método estático para convertir temperaturas
  • Métodos de clase para añadir lecturas y calcular promedios

Pruébalo tú mismo

from temperature import Temperature

# Gestor de casos de prueba para realizar pruebas exhaustivas
test_case = input()

if test_case == "default_test":
    # Prueba la funcionalidad básica
    Temperature.celsius_readings = []
    Temperature.add_reading(25)
    Temperature.add_reading(30)
    Temperature.add_reading(27)
    
    print(f"Average reading: {Temperature.average_reading()}")
    print(f"22°C is {Temperature.celsius_to_fahrenheit(22)}°F")

elif test_case == "empty_readings":
    # Prueba average_reading sin lecturas
    Temperature.celsius_readings = []
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "single_reading":
    # Prueba con una sola lectura
    Temperature.celsius_readings = []
    Temperature.add_reading(100)
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "negative_values":
    # Prueba con valores de temperatura negativos
    Temperature.celsius_readings = []
    Temperature.add_reading(-10)
    Temperature.add_reading(-20)
    Temperature.add_reading(-30)
    print(f"Average reading: {Temperature.average_reading()}")
    print(f"-15°C is {Temperature.celsius_to_fahrenheit(-15)}°F")

elif test_case == "zero_value":
    # Prueba con una lectura de 0°C
    print(f"0°C is {Temperature.celsius_to_fahrenheit(0)}°F")

elif test_case == "extreme_values":
    # Prueba con valores de temperatura extremos
    absolute_zero = -273.15  # cero absoluto en grados Celsius
    sun_surface = 5500  # temperatura aproximada de la superficie del Sol en grados Celsius
    
    print(f"{absolute_zero}°C is {Temperature.celsius_to_fahrenheit(absolute_zero)}°F")
    print(f"{sun_surface}°C is {Temperature.celsius_to_fahrenheit(sun_surface)}°F")

elif test_case == "reset_readings":
    # Prueba el restablecimiento de las lecturas
    Temperature.celsius_readings = []
    Temperature.add_reading(10)
    Temperature.add_reading(20)
    Temperature.add_reading(30)
    print(f"Average reading before reset: {Temperature.average_reading()}")
    
    Temperature.celsius_readings = []
    print(f"Average reading after reset: {Temperature.average_reading()}")

elif test_case == "decimal_values":
    # Prueba con valores decimales
    Temperature.celsius_readings = []
    Temperature.add_reading(36.5)  # Temperatura corporal normal
    Temperature.add_reading(37.2)  # Fiebre leve
    Temperature.add_reading(36.9)  # Variación normal
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "many_readings":
    # Prueba con muchas lecturas
    Temperature.celsius_readings = []
    for i in range(1, 101):
        Temperature.add_reading(i)
    print(f"Average reading with 100 values: {Temperature.average_reading()}")
quiz iconPonte a prueba

Esta lección incluye un breve cuestionario. Empieza la lección para responderlo y registrar tu progreso.

Todas las lecciones de Programación orientada a objetos

Practica por tu cuenta: Compilador de Python online