0Pricing
Python Academy · Урок

Параметры неизменяемости и сравнения

Создавайте неизменяемые упорядоченные датаклассы

«Параметры неизменяемости и сравнения» — бесплатный урок Python Academy на CoddyKit. Это урок 3 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения Python Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс Python Academy содержит 4 уроков всего.

Параметры декоратора

Декоратор @dataclass принимает именованные аргументы, управляющие создаваемыми методами. Наиболее полезны параметры frozen и order.

  • frozen=True делает экземпляры неизменяемыми.
  • order=True добавляет операторы сравнения.

Неизменяемые датаклассы

При использовании frozen=True созданный класс запрещает присваивание атрибутов после создания экземпляра. Любая попытка вызывает FrozenInstanceError.

from dataclasses import dataclass, FrozenInstanceError

@dataclass(frozen=True)
class Point:
    x: int
    y: int

p = Point(1, 2)
try:
    p.x = 99
except FrozenInstanceError as e:
    print('Cannot modify:', e)

Преимущества неизменяемости

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

Неизменяемость означает хешируемость

Неизменяемый класс данных по умолчанию является хешируемым, поэтому его экземпляры можно использовать в множествах или в качестве ключей словаря. Изменяемые классы данных не являются хешируемыми, если явно не включить эту возможность.

from dataclasses import dataclass

@dataclass(frozen=True)
class Point:
    x: int
    y: int

seen = {Point(0, 0), Point(1, 1), Point(0, 0)}
print(len(seen))

Замена неизменяемых значений

Поскольку изменить неизменяемый экземпляр нельзя, используйте dataclasses.replace(), чтобы создать изменённую копию. Исходный объект останется без изменений.

from dataclasses import dataclass, replace

@dataclass(frozen=True)
class Point:
    x: int
    y: int

p = Point(1, 2)
q = replace(p, y=99)
print(p)
print(q)

Упорядоченные классы данных

По умолчанию класс данных поддерживает только ==. Добавьте order=True, чтобы также сгенерировать <, <=, > и >=.

from dataclasses import dataclass

@dataclass(order=True)
class Version:
    major: int
    minor: int

print(Version(1, 2) < Version(1, 5))
print(Version(2, 0) > Version(1, 9))

Как сравнивается порядок

Порядок сравнивает поля как кортеж слева направо, в порядке их объявления. Первое поле имеет наибольший приоритет.

from dataclasses import dataclass

@dataclass(order=True)
class Version:
    major: int
    minor: int

# major compared first, then minor
print(Version(1, 9) < Version(2, 0))

Сортировка экземпляров классов данных

Поскольку упорядоченные классы данных определяют операторы сравнения, их список можно напрямую отсортировать с помощью sorted().

from dataclasses import dataclass

@dataclass(order=True)
class Score:
    points: int
    name: str

data = [Score(50, 'B'), Score(90, 'A'), Score(70, 'C')]
for s in sorted(data):
    print(s)

Управление ключом сортировки

Чтобы сортировать не в естественном порядке полей, поместите первым скрытое поле сортировки с помощью field(init=False) и задайте его в __post_init__. Остальные поля можно исключить из сравнения с помощью compare=False.

from dataclasses import dataclass, field

@dataclass(order=True)
class Item:
    sort_index: int = field(init=False, repr=False)
    name: str = field(compare=False, default='')
    priority: int = 0

    def __post_init__(self):
        self.sort_index = self.priority

print(Item(name='b', priority=2) > Item(name='a', priority=1))

Сочетание параметров frozen и order

Параметры можно сочетать. Неизменяемый упорядоченный класс данных становится отличным неизменяемым типом-значением с поддержкой сравнения — идеальным для ключей, номеров версий или координат.

from dataclasses import dataclass

@dataclass(frozen=True, order=True)
class SemVer:
    major: int
    minor: int
    patch: int

versions = {SemVer(1, 0, 0): 'stable'}
print(SemVer(1, 0, 0) < SemVer(1, 1, 0))
print(versions[SemVer(1, 0, 0)])

eq и значение по умолчанию

Параметр eq управляет генерацией __eq__. По умолчанию он имеет значение True. Обратите внимание: для order=True требуется eq=True, поскольку упорядочивание основано на равенстве.

from dataclasses import dataclass

@dataclass(eq=True)
class Tag:
    name: str

print(Tag('x') == Tag('x'))
print(Tag('x') == Tag('y'))

Быстрая проверка

Что произойдёт, если присвоить значение полю экземпляра неизменяемого класса данных?

Повторение

Вы научились создавать неизменяемые упорядоченные классы данных.

  • frozen=True запрещает изменение и делает экземпляры хешируемыми.
  • Используйте replace() для создания изменённых копий.
  • order=True генерирует операторы сравнения, которые сравнивают поля как кортеж.
  • Сочетайте оба параметра для надёжных типов-значений.

Часто задаваемые вопросы

Урок «Параметры неизменяемости и сравнения» бесплатный?

Да — полный текст урока «Параметры неизменяемости и сравнения» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс Python Academy, подпишись на CoddyKit PRO. Курс Python Academy содержит 4 уроков всего.

Чему я научусь в уроке «Параметры неизменяемости и сравнения»?

Создавайте неизменяемые упорядоченные датаклассы Ты практикуешь Python Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.

Нужен ли мне опыт, чтобы начать Python Academy?

Предыдущий опыт не требуется. Python Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 3 из 4.

Сколько времени занимает урок «Параметры неизменяемости и сравнения»?

Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.

Можно ли писать и запускать код в этом уроке Python Academy?

Да. Каждый урок Python Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.

Все уроки этого курса

  1. Определение датакласса
  2. Значения по умолчанию и field()
  3. Параметры неизменяемости и сравнения
  4. Библиотека attrs
← Назад к Python Academy