2.20. Первый класс

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

2.20.1. Ключевое слово class

Ключевое слово – class. Тело содержит метод __init__, который выполняется каждый раз при создании нового экземпляра:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

p = Point(3, 4)
print(p.x, p.y)

Вывод:

3 4

Point – это класс; pэкземпляр этого класса. Скобки в вызове Point(3, 4) вызывают __init__, который присваивает аргументы атрибутам нового экземпляра. self – это общепринятое имя для экземпляра; self.x задаёт атрибут, который будут читать остальные методы экземпляра.

2.20.2. Когда использовать класс

Прибегайте к классу, когда одновременно верно следующее:

  • Несколько связанных значений путешествуют вместе повсюду (x и y точки; значение, единица измерения и временная метка показания датчика).

  • Несколько функций принимают этот же набор значений и оперируют ими.

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

Если данные одноразовые, обычно достаточно простого dict или tuple. Если вам нужен лишь один набор констант, подойдут переменные уровня модуля. Классы – не контейнер по умолчанию; они оправдывают своё место, когда состояние и поведение хотят держаться вместе.

2.20.3. Что делает __init__

__init__ – это просто обычный метод. Всё, что присваивается self внутри него, становится атрибутом нового экземпляра:

class Sensor:
    def __init__(self, name, unit):
        self.name = name
        self.unit = unit
        self.readings = []

temp = Sensor("temperature", "C")
print(temp.name, temp.unit, temp.readings)

Вывод:

temperature C []

readings инициализируется пустым списком – каждый новый экземпляр получает свой собственный список, а не общий. Всё, что не присваивается self, локально для __init__ и исчезает при его возврате.