Методы: обычные, classmethod и staticmethod
У методов Python три лика: обычный с self, classmethod с cls и staticmethod без ничего. Строим альтернативный конструктор from_string и расставляем границы.
Редакция Питоники
До сих пор все методы были «обычными»: первым параметром self, вызываются на объекте. Обычный метод работает с конкретным объектом — self его пропуск к атрибутам: корзина покупок помнит свои товары, и каждый вызов метода меняет именно свою корзину. Но у Python есть ещё два вида методов, которые закрывают другие задачи: конструирование объекта из нестандартных данных и утилиты, которым состояние не нужно вовсе. Если механика self ещё туманна, начните с урока про __init__ и self.
Обычный метод: self и состояние объекта
class Cart:
def __init__(self):
self.items = []
def add(self, name):
self.items.append(name)
def total(self):
return len(self.items)
cart = Cart()
cart.add("хлеб")
cart.add("молоко")
print(cart.total())
2
@classmethod: метод класса и конструктор from_string
Декоратор @classmethod меняет правила: первый параметр метода — не объект, а сам класс, по традиции названный cls. Python передаёт его автоматически при вызове и через класс, и через экземпляр. classmethod нужен тогда, когда методу важен класс: чаще всего это альтернативный конструктор. Такой метод принимает данные в неудобном формате, разбирает их и возвращает новый экземпляр.
class Meeting:
def __init__(self, day, month, year):
self.day = day
self.month = month
self.year = year
@classmethod
def from_string(cls, text):
day, month, year = text.split(".")
return cls(int(day), int(month), int(year))
def describe(self):
print(f"Встреча: {self.day}.{self.month}.{self.year}")
m = Meeting.from_string("15.10.2026")
m.describe()
Встреча: 15.10.2026
| Вид | Декоратор | Первый аргумент | Для чего |
|---|---|---|---|
| обычный | — | self — экземпляр | работа с состоянием объекта |
| метод класса | @classmethod | cls — сам класс | альтернативные конструкторы, атрибуты класса |
| статический | @staticmethod | нет | утилита, относящаяся к сущности класса |
@staticmethod — метод без self и без cls: обычная функция, которой логично жить внутри класса, потому что она относится к его сущности. Проверка email до создания пользователя — классика: валидация нужна и до, и после создания объектов, а состояния она не трогает. Вызывается одинаково через класс и через экземпляр.
class User:
def __init__(self, email):
self.email = email
@staticmethod
def is_valid_email(email):
return "@" in email
print(User.is_valid_email("anna@example.com"))
print(User.is_valid_email("anna-example.com"))
u = User("boris@example.ru")
print(u.is_valid_email("test@mail.ru"))
True False True
Три вида методов — три уровня доступа к сущности: объект (self), класс (cls), ничего. Дальше: инкапсуляция — как спрятать внутренности класса за публичным интерфейсом; @property — вычисляемые атрибуты, которые выглядят как поля. А альтернативные конструкторы ещё не раз выручат в проектах этого курса.
Сначала предскажи ответ в голове — это главный навык программиста.
class Temperature:
def __init__(self, celsius):
self.celsius = celsius
@classmethod
def from_fahrenheit(cls, f):
return cls((f - 32) * 5 / 9)
t = Temperature.from_fahrenheit(32)
print(t.celsius)
class Box:
def __init__(self, weight):
self.weight = weight
def show(self):
print(f"Вес: {self.weight}")
box = Box(7)
Box.show(box)
class Math:
@staticmethod
def double(x):
return x * 2
print(Math.double(21))
1. Первый параметр обычного метода — это...
2. Что получает @classmethod первым параметром?
3. Зачем нужен альтернативный конструктор from_string?
4. Когда уместен @staticmethod?
5. Можно ли вызвать статический метод через экземпляр?
6. cls — это...
Создайте класс Money: __init__(self, amount) сохраняет сумму; classmethod from_kopecks(kopecks) переводит копейки в рубли (делением на 100) и возвращает новый объект; @staticmethod is_valid_amount(amount) возвращает True для неотрицательных чисел. Создайте объект из 1250 копеек и выведите две строки: сумму и результат проверки 250.
Чем classmethod отличается от обычного метода?
Обычный метод первым параметром получает экземпляр (self) и работает с его атрибутами. classmethod получает сам класс (cls): ему неважно, сколько объектов существует, — он создаёт новые (альтернативные конструкторы) или читает общие атрибуты класса.
Урок 2: __init__ и selfКогда использовать staticmethod?
Когда метод не трогает ни объект, ни класс: чистая функция, логично живущая внутри класса. Проверки формата, конвертации единиц, вспомогательные расчёты. Если внутри понадобится self или cls — это сигнал сменить вид метода.
Зачем создавать экземпляр через cls, а не через имя класса?
cls указывает на класс, через который вызван метод, включая наследников: Money.from_kopecks(1250) создаст Money, а DiscountMoney.from_kopecks(1250) — DiscountMoney. Жёстко прописанное имя класса сломало бы это поведение.
Можно ли вызывать classmethod и staticmethod на экземпляре?
Да: Python сам передаёт правильный cls или ничего. m.is_valid_amount(250) работает как Money.is_valid_amount(250). Выбор «через класс или через экземпляр» — вопрос читаемости: фабрики и утилиты обычно вызывают через класс.
Понравился урок? Сошлитесь на него
«classmethod нужен тогда, когда методу важен класс: чаще всего это альтернативный конструктор.»
Скопируйте готовую ссылку в формате HTML, Markdown или чистый адрес и вставьте в статью на Habr, VC, Telegram-канал или свой блог — так о проекте узнают новые читатели.
Что читать дальше
ООП · Урок 2
__init__ и self: как рождается объект
__init__ задаёт объекту стартовое состояние, а self — это сам объект внутри его методов. Разбираем механику вызова hero.heal(30) до последней детали.
ООП · Урок 3
Атрибуты класса и атрибуты экземпляра
Атрибут класса один на всех, атрибут экземпляра — личный. Разбираем порядок поиска атрибутов и классическую ловушку общего списка — с исправлением.
ООП · Урок 5
Инкапсуляция: _protected и __private
Одно подчёркивание — договорённость, два — искажение имени. Учимся прятать детали класса за публичным интерфейсом и понимать name mangling.
Похожие уроки по темам
Подобраны автоматически по пересечению тем и ключевых слов.
pytest · Урок 16
Тестирование классов: методы, состояние и Test-классы
Корзина магазина как подопытная: фикстура раздаёт каждому тесту свежий объект, Test-класс наводит порядок в методах — и ни одно состояние не протекает.
тестирование методов класса pythonpytest методы test_
FastAPI · Урок 1
Что такое API и REST: введение в FastAPI для начинающих
Понять, что такое API, REST, HTTP-методы и JSON — и подготовиться к первому приложению на FastAPI.
http методыhttp методы get post put delete
ООП · Урок 7
Наследование: расширяем классы
Наследование — способ расширять классы без переписывания: потомок получает всё от родителя, переопределяет и дополняет через super(). Родство проверяет isinstance.
переопределение методов pythonрасширение класса python