Menu
Coddy logo textTech

Métodos Estáticos e de Classe

Parte da seção Object Oriented Programming do Journey de Python da Coddy — lição 39 de 64.

Além dos métodos de instância regulares, as classes podem ter métodos estáticos e métodos de classe que servem a propósitos diferentes.

Aqui está um exemplo de um método estático:

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

Métodos estáticos não precisam de self e funcionam como funções regulares. Chame-os diretamente da classe:

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

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

Aqui está um exemplo de um método de classe:

class Person:
    count = 0  # Variável de classe
    
    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")

Métodos de classe recebem a própria classe (cls) como o primeiro parâmetro:

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

Use métodos de classe como construtores alternativos:

anonymous = Person.create_anonymous()
print(anonymous.name)      # Anônimo
print(Person.get_count())  # 3

Compare todos os três tipos de métodos em uma classe:

class Calculator:
    brand = "Python Calc"
    
    def __init__(self, owner):
        self.owner = owner
    
    # Método de instância - precisa de self, acessa dados da instância
    def show_owner(self):
        return f"Owned by {self.owner}"
    
    # Método de classe - precisa de cls, acessa dados da classe
    @classmethod
    def get_brand(cls):
        return cls.brand
    
    # Método estático - não precisa de nenhum dos dois, apenas uma função utilitária
    @staticmethod
    def multiply(x, y):
        return x * y
calc = Calculator("Alice")
print(calc.show_owner())        # Pertence a Alice
print(Calculator.get_brand())   # Python Calc
print(Calculator.multiply(4, 5)) # 20

Saída:

8
True
2
Anonymous
3
Owned by Alice
Python Calc
20

Você também pode chamar métodos de classe e estáticos a partir de instâncias:

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

Principais Diferenças:

  • Métodos de instância: Precisam de self, acessam dados da instância
  • Métodos de classe: Precisam de cls, acessam dados da classe, bons para construtores alternativos
  • Métodos estáticos: Não precisam de nenhum dos dois, apenas funções utilitárias relacionadas à classe

Ponto Chave: Use @staticmethod para funções utilitárias que pertencem logicamente à classe, mas não precisam de dados da classe ou da instância. Use @classmethod quando você precisar de acesso à própria classe, como para construtores alternativos ou para acessar variáveis de classe.

challenge icon

Desafio

Fácil

Neste desafio, você implementará uma classe Temperature com funcionalidades específicas enquanto utiliza um framework de testes abrangente.

Você precisa editar apenas o arquivo temperature.py, seguindo os comentários TODO que guiam sua implementação. A classe deve incluir:

  • Uma variável de classe para rastrear as leituras de temperatura
  • Um método estático para conversão de temperatura
  • Métodos de classe para adicionar leituras e calcular médias

Folha de consulta

As classes podem ter três tipos de métodos: métodos de instância, métodos estáticos e métodos de classe.

Métodos estáticos usam o decorador @staticmethod, não precisam de self e funcionam como funções regulares:

class MathHelper:
    @staticmethod
    def add(a, b):
        return a + b

# Call directly from class
result = MathHelper.add(5, 3)

Métodos de classe usam o decorador @classmethod e recebem a classe (cls) como primeiro parâmetro:

class Person:
    count = 0
    
    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")

# Uso
print(Person.get_count())
anonymous = Person.create_anonymous()

Principais diferenças:

  • Métodos de instância: Precisam de self, acessam dados da instância
  • Métodos de classe: Precisam de cls, acessam dados da classe, são bons para construtores alternativos
  • Métodos estáticos: Não precisam de nenhum dos dois, são apenas funções utilitárias relacionadas à classe

Tanto os métodos de classe quanto os estáticos podem ser chamados a partir da classe ou de instâncias:

Calculator.multiply(4, 5)  # A partir da classe
calc.multiply(4, 5)        # A partir da instância

Experimente você mesmo

from temperature import Temperature

# Manipulador de casos de teste para testes abrangentes
test_case = input()

if test_case == "default_test":
    # Testa a funcionalidade 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":
    # Testa average_reading sem leituras
    Temperature.celsius_readings = []
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "single_reading":
    # Testa com uma única leitura
    Temperature.celsius_readings = []
    Temperature.add_reading(100)
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "negative_values":
    # Testa com 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":
    # Testa com uma leitura de 0°C
    print(f"0°C is {Temperature.celsius_to_fahrenheit(0)}°F")

elif test_case == "extreme_values":
    # Testa com valores de temperatura extremos
    absolute_zero = -273.15  # zero absoluto em Celsius
    sun_surface = 5500  # temperatura aproximada da superfície do sol em 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":
    # Testa a redefinição das leituras
    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":
    # Testa com valores decimais
    Temperature.celsius_readings = []
    Temperature.add_reading(36.5)  # Temperatura corporal normal
    Temperature.add_reading(37.2)  # Febre leve
    Temperature.add_reading(36.9)  # Variação normal
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "many_readings":
    # Testa com muitas leituras
    Temperature.celsius_readings = []
    for i in range(1, 101):
        Temperature.add_reading(i)
    print(f"Average reading with 100 values: {Temperature.average_reading()}")
quiz iconTeste seus conhecimentos

Esta lição inclui um quiz rápido. Comece a lição para respondê-lo e acompanhar seu progresso.

Todas as lições de Object Oriented Programming