В Python методы бывают трёх основных типов: методы экземпляра, методы класса и статические методы. Исторически Python поддерживал только методы экземпляра (с первым параметром self). Со временем появилась необходимость в дополнительных типах методов: доступных через класс без привязки к объекту и с доступом к самому классу.
Проблема: часто требуется создавать методы, которые не зависят от состояния экземпляра объекта (например, фабричные методы) или вообще не нуждаются в контексте класса, но логически входят в структуру класса.
Решение: используются декораторы @classmethod и @staticmethod.
Пример кода:
class Example: def instance_method(self): return f'instance: {self}' @classmethod def class_method(cls): return f'class: {cls}' @staticmethod def static_method(): return 'static'
Ключевые особенности:
Может ли статический метод обращаться к атрибутам класса и экземпляра?
Нет, статический метод не получает ссылку ни на класс, ни на объект.
class A: x = 10 @staticmethod def f(): # print(self.x) # Ошибка pass
Могут ли методы класса быть переопределены в наследниках?
Да, при вызове classmethod через потомка первым аргументом всегда будет фактический класс, а не родитель.
class Base: @classmethod def name(cls): return cls.__name__ class Child(Base): pass Child.name() # "Child"
Почему нельзя использовать self для методов класса?
Потому что метод класса не связан с конкретным объектом, а с классом в целом; self не доступен без создания экземпляра.
Фабричный метод определили как staticmethod, а внутри пытаются создать экземпляр класса через self, что приводит к ошибкам или дублированию кода.
Плюсы:
Минусы:
Фабрика объявлена через classmethod, внутри используется фактический класс (cls) для создания экземпляра. Наследники корректно создаются через эту фабрику.
Плюсы:
Минусы: