Параметры неизменяемости и сравнения
Создавайте неизменяемые упорядоченные датаклассы
«Параметры неизменяемости и сравнения» — бесплатный урок 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 — локальная установка не требуется.
Все уроки этого курса
- Определение датакласса
- Значения по умолчанию и field()
- Параметры неизменяемости и сравнения
- Библиотека attrs