Все разделы
Выбрать школу

Школа. Увлечения. Большое будущее.

PROSCHOOLS · ОБРАЗОВАНИЕ РЯДОМ

Ваш город

Выберите город, чтобы находить образование и возможности рядом.

Как учитываем городКаталог и кнопки «Выбрать школу» покажут школы выбранного города.Онлайн-курсы, учебник, ГДЗ и задания к экзаменам доступны по всей России.

Популярные города

Будет выбран: Вся Россия

Учебные материалы останутся прежними.

Поиск по сайту

По всему сайтуШколы выбранного города — выше в результатах

С чего начнём?

↑ ↓ — выбрать результат · Enter — открыть · Esc — закрыть

Классы: первые шаги в объектно-ориентированное программирование

💻 Информатика · 10 класс

Класс объединяет данные и действия над ними: студент хранит имя и оценки и умеет считать средний балл. Разберём __init__, self, методы и простое наследование.

Программный код на экране
Программный код на экранеMartin Vorel · Wikimedia Commons · CC BY-SA 4.0

Зачем нужны классы

По официальному учебнику Python, класс объединяет данные и функциональность: он создаёт новый тип объектов, каждый из которых хранит своё состояние (атрибуты) и умеет выполнять действия (методы). Если словарь с оценками — это «коробка с данными», то объект — это «сотрудник», который помнит свои данные и знает, что с ними делать.

Пример 1. Класс Student

class Student:
    def __init__(self, name):
        if not isinstance(name, str) or not name.strip():
            raise ValueError('нужна непустая строка имени')
        self.name = name.strip()
        self.marks = []

    def add_mark(self, mark):
        if type(mark) is not int or mark < 1 or mark > 5:
            raise ValueError('оценка должна быть от 1 до 5')
        self.marks.append(mark)

    def average(self):
        if not self.marks:
            return None
        return sum(self.marks) / len(self.marks)

anya = Student('Аня')
anya.add_mark(5)
anya.add_mark(4)
print(anya.average())  # 4.5

Вызов Student('Аня') создаёт экземпляр; затем __init__ инициализирует уже созданный объект. Поэтому __init__ точнее называть инициализатором, а не операцией выделения нового объекта. Параметр self — сам создаваемый объект; через self.name и self.marks мы прикрепляем к нему данные. Внутри методов данные доступны как self.marks — поэтому average не нужен список извне. В этой модели имя должно быть непустой строкой, а оценка — целым числом от 1 до 5. Проверки отклоняют неправильные вызовы. Self — принятое имя первого параметра обычного метода экземпляра, а не отдельное ключевое слово.

Пример 2. Класс BankAccount

Учебный счёт показывает независимость состояний. В этом примере баланс и суммы — целые условные единицы; это не финансовое приложение. Проверки методов не запрещают внешнему коду напрямую присвоить self.balance другое значение: атрибут остаётся публичным.

class BankAccount:
    def __init__(self, owner, balance=0):
        if balance < 0:
            raise ValueError('баланс не может быть отрицательным')
        self.owner = owner
        self.balance = balance

    def deposit(self, amount):
        if amount <= 0:
            raise ValueError('вклад должен быть положительным')
        self.balance += amount

    def withdraw(self, amount):
        if amount <= 0:
            raise ValueError('сумма снятия должна быть положительной')
        if amount > self.balance:
            raise ValueError('недостаточно средств')
        self.balance -= amount

Создадим два счёта: a = BankAccount('Аня', 100), b = BankAccount('Борис', 50). Снятие со счёта a меняет только a.balance: b остаётся равен 50. Здесь self.balance относится к конкретному экземпляру. Список self.marks создаётся заново в каждом __init__, поэтому оценки разных учеников тоже независимы. Если вынести marks = [] в тело класса, список станет общим атрибутом класса, и изменения будут неожиданно видны нескольким ученикам. Неудачные операции (снять 0, -5 или 21 при балансе 20) отклоняются исключением и не меняют состояние.

Наследование: класс-наследник

Наследник использует поведение базового класса и может добавлять или переопределять методы. Вызов super помогает выполнить базовую инициализацию. Диапазон возраста 6–19 ниже — условие учебной модели, а не общее правило поступления в школу.

class AgedStudent(Student):
    def __init__(self, name, age):
        if type(age) is not int or age < 6 or age > 19:
            raise ValueError('возраст школьника: от 6 до 19')
        super().__init__(name)
        self.age = age

    def is_at_least_15(self):
        return self.age >= 15

Вызов super().__init__(name) делегирует инициализацию базовому классу — проверки имени не дублируются. AgedStudent('Дарья', 16) умеет всё, что Student: add_mark и average работают без изменений, а метод is_at_least_15 добавлен только наследнику.

Проверь себя

  1. Что выведет print(anya.average()), если оценок не добавляли? Ответ: None — метод average так написан, что безопасен для пустого списка.
  2. Зачем методам первый параметр self? Ответ: через него метод получает объект, у которого вызван, и читает его атрибуты.
  3. Что произойдёт при Student('')? Ответ: ValueError — __init__ поднимает исключение: вызов класса не возвращает успешно инициализированный экземпляр. Само выделение объекта происходит раньше инициализации.
  4. AgedStudent('Ева', 10).is_at_least_15()? Ответ: False — 10 меньше 15; при этом add_mark(5) всё равно работает, метод унаследован.

Кратко о главном

Класс — шаблон объектов с данными (атрибуты) и действиями (методы). __init__ готовит объект, при обычном вызове метода экземпляр передаётся первым аргументом self; наследование позволяет использовать и переопределять поведение базы. Проверяйте данные через raise ValueError — плохие объекты не должны создаваться.

Связанные материалы

Источники и материалы