Menu
Coddy logo textTech

Статические методы и методы класса

Часть раздела Object Oriented Programming путешествия по Python на Coddy — урок 39 из 64.

Помимо обычных методов экземпляра, классы могут иметь статические методы и методы класса, которые служат разным целям.

Вот пример статического метода:

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

Статическим методам не нужен self, и они работают как обычные функции. Вызывайте их напрямую из класса:

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

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

Вот пример метода класса:

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")

Методы класса получают сам класс (cls) в качестве первого параметра:

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

Используйте методы класса в качестве альтернативных конструкторов:

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

Сравните все три типа методов в одном классе:

class Calculator:
    brand = "Python Calc"
    
    def __init__(self, owner):
        self.owner = owner
    
    # Метод экземпляра — требует self, обращается к данным экземпляра
    def show_owner(self):
        return f"Owned by {self.owner}"
    
    # Метод класса — требует cls, обращается к данным класса
    @classmethod
    def get_brand(cls):
        return cls.brand
    
    # Статический метод — не требует ни того, ни другого, просто утилитарная функция
    @staticmethod
    def multiply(x, y):
        return x * y
calc = Calculator("Alice")
print(calc.show_owner())        # Владелец: Alice
print(Calculator.get_brand())   # Python Calc
print(Calculator.multiply(4, 5)) # 20

Вывод:

8
True
2
Anonymous
3
Owned by Alice
Python Calc
20

Вы также можете вызывать методы класса и статические методы из экземпляров:

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

Ключевые различия:

  • Методы экземпляра: требуют self, имеют доступ к данным экземпляра
  • Методы класса: требуют cls, имеют доступ к данным класса, подходят для альтернативных конструкторов
  • Статические методы: не требуют ни того, ни другого, просто вспомогательные функции, связанные с классом

Ключевой момент: Используйте @staticmethod для вспомогательных функций, которые логически относятся к классу, но не требуют данных класса или экземпляра. Используйте @classmethod, когда вам нужен доступ к самому классу, например, для альтернативных конструкторов или доступа к переменным класса.

challenge icon

Задание

Легко

В этом испытании вы реализуете класс Temperature с определенной функциональностью, используя комплексную среду тестирования.

Вам нужно отредактировать только файл temperature.py, следуя комментариям TODO, которые направляют вашу реализацию. Класс должен включать:

  • Переменную класса для отслеживания показаний температуры
  • Статический метод для конвертации температуры
  • Методы класса для добавления показаний и вычисления средних значений

Шпаргалка

Классы могут иметь три типа методов: методы экземпляра, статические методы и методы класса.

Статические методы используют декоратор @staticmethod, не требуют self и работают как обычные функции:

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

# Вызов напрямую из класса
result = MathHelper.add(5, 3)

Методы класса используют декоратор @classmethod и получают класс (cls) в качестве первого параметра:

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")

# Использование
print(Person.get_count())
anonymous = Person.create_anonymous()

Ключевые различия:

  • Методы экземпляра: требуют self, имеют доступ к данным экземпляра
  • Методы класса: требуют cls, имеют доступ к данным класса, подходят для создания альтернативных конструкторов
  • Статические методы: не требуют ни того, ни другого, просто вспомогательные функции, связанные с классом

Как методы класса, так и статические методы можно вызывать из класса или из экземпляров:

Calculator.multiply(4, 5)  # Из класса
calc.multiply(4, 5)        # Из экземпляра

Попробуйте сами

from temperature import Temperature

# Обработчик тестовых случаев для комплексного тестирования
test_case = input()

if test_case == "default_test":
    # Тестирование базовой функциональности
    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":
    # Тестирование average_reading без показаний
    Temperature.celsius_readings = []
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "single_reading":
    # Тестирование с одним показанием
    Temperature.celsius_readings = []
    Temperature.add_reading(100)
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "negative_values":
    # Тестирование с отрицательными значениями температуры
    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":
    # Тестирование с показанием 0°C
    print(f"0°C is {Temperature.celsius_to_fahrenheit(0)}°F")

elif test_case == "extreme_values":
    # Тестирование с экстремальными значениями температуры
    absolute_zero = -273.15  # абсолютный ноль в Цельсиях
    sun_surface = 5500  # примерная температура поверхности Солнца в Цельсиях
    
    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":
    # Тестирование сброса показаний
    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":
    # Тестирование с десятичными значениями
    Temperature.celsius_readings = []
    Temperature.add_reading(36.5)  # Нормальная температура тела
    Temperature.add_reading(37.2)  # Небольшая лихорадка
    Temperature.add_reading(36.9)  # Нормальное отклонение
    print(f"Average reading: {Temperature.average_reading()}")

elif test_case == "many_readings":
    # Тестирование с большим количеством показаний
    Temperature.celsius_readings = []
    for i in range(1, 101):
        Temperature.add_reading(i)
    print(f"Average reading with 100 values: {Temperature.average_reading()}")
quiz iconПроверьте себя

В этом уроке есть небольшой тест. Начните урок, чтобы ответить на вопросы и сохранить прогресс.

Все уроки раздела Object Oriented Programming