СДЕЛАЙТЕ СВОИ УРОКИ ЕЩЁ ЭФФЕКТИВНЕЕ, А ЖИЗНЬ СВОБОДНЕЕ

Благодаря готовым учебным материалам для работы в классе и дистанционно

Скидки до 50 % на комплекты
только до

Готовые ключевые этапы урока всегда будут у вас под рукой

Организационный момент

Проверка знаний

Объяснение материала

Закрепление изученного

Итоги урока

Методическая разработка «Протокол дескриптора в Python»

Категория: Информатика

Нажмите, чтобы узнать подробности

Просмотр содержимого документа
«Методическая разработка «Протокол дескриптора в Python»»

МУНИЦИПАЛЬНОЕ АВТОНОМНОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ ДОПОЛНИТЕЛЬНОГО ОБРАЗОВАНИЯ

«ЦЕНТР ДЕТСКОГО ТЕХНИЧЕСКОГО ТВОРЧЕСТВА»













Методическая разработка

«Протокол дескриптора в Python»

к дополнительной общеобразовательной

общеразвивающей программе

технической направленности

«Программирование на Python»



Возраст детей: 10-17 лет









Автор: Костычев Вадим Александрович











г. Заречный Пензенской области

2026 г.

Данный материал предназначен для преподавателей информатики, программирования и студентов (учащихся), изучающих язык программирования Python. Он может быть использован как на лекциях, так и при проведении практических занятий или самостоятельной работе.

Цель: сформировать у обучающихся понимание механизма дескрипторов как одного из фундаментальных протоколов Python, лежащего в основе работы property, classmethod, staticmethod и других механизмов языка, а также научить создавать собственные дескрипторы для управления доступом к атрибутам.

Задачи:

  1. Объяснить, что такое дескриптор и зачем он нужен.

  2. Познакомить с протоколом дескриптора: методами __get__, __set__, __delete__.

  3. Различать data-дескрипторы и non-data-дескрипторы.

  4. Показать, как дескрипторы используются в самом Python (property, classmethod, staticmethod).

  5. Научить создавать собственные дескрипторы для валидации и управления атрибутами.

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

Что такое дескриптор?

Дескриптор — это объект, который управляет доступом к атрибуту другого объекта через специальные магические методы.

Простыми словами:

Дескриптор — это «посредник», который перехватывает операции чтения, записи и удаления атрибута.

Дескрипторы лежат в основе многих встроенных механизмов Python:

  • property

  • @classmethod

  • @staticmethod

  • super()

  • методы классов в целом

Протокол дескриптора

Чтобы объект стал дескриптором, он должен реализовать хотя бы один из следующих методов:

class Descriptor:

def __get__(self, instance, owner=None):

# Вызывается при чтении атрибута

pass


def __set__(self, instance, value):

# Вызывается при записи атрибута

pass


def __delete__(self, instance):

# Вызывается при удалении атрибута

pass


Параметры методов:

Параметр

Значение

self

Сам объект-дескриптор

instance

Экземпляр класса, у которого вызван атрибут

owner

Класс, которому принадлежит атрибут

value

Значение, которое присваивается


Типы дескрипторов

Data-дескриптор (данные)

Реализует и __get__, и __set__ (или __delete__).

Имеет высокий приоритет — перекрывает атрибуты в __dict__ экземпляра.

Non-data-дескриптор (только чтение)

Реализует только __get__.

Имеет низкий приоритет — атрибут в __dict__ экземпляра перекроет дескриптор.

Порядок поиска атрибута:

  1. Data-дескриптор из класса

  2. Атрибут в __dict__ экземпляра

  3. Non-data-дескриптор из класса

  4. Атрибут в __dict__ класса

  5. __getattr__, если определён

Простой пример дескриптора

Создадим дескриптор для логирования доступа к атрибуту:

class LoggedAttribute:

def __init__(self, name):

self.name = name


def __get__(self, instance, owner):

print(f"[GET] Чтение {self.name}")

return instance.__dict__.get(self.name)


def __set__(self, instance, value):

print(f"[SET] Запись {self.name} = {value}")

instance.__dict__[self.name] = value


def __delete__(self, instance):

print(f"[DEL] Удаление {self.name}")

del instance.__dict__[self.name]



class Person:

name = LoggedAttribute("_name")

age = LoggedAttribute("_age")


def __init__(self, name, age):

self.name = name # вызовет __set__

self.age = age # вызовет __set__



p = Person("Анна", 25)

# [SET] Запись _name = Анна

# [SET] Запись _age = 25


print(p.name) # [GET] Чтение _name → Анна

p.age = 30 # [SET] Запись _age = 30

del p.name # [DEL] Удаление _name


Практический пример: валидация атрибутов

Дескрипторы идеально подходят для проверки значений при присваивании:

class Validator:

def __init__(self, min_value=None, max_value=None):

self.min_value = min_value

self.max_value = max_value


def __set_name__(self, owner, name):

self.name = name


def __set__(self, instance, value):

if self.min_value is not None and value

raise ValueError(f"{self.name} должно быть = {self.min_value}")

if self.max_value is not None and value self.max_value:

raise ValueError(f"{self.name} должно быть

instance.__dict__[self.name] = value


def __get__(self, instance, owner):

if instance is None:

return self

return instance.__dict__.get(self.name)



class Product:

price = Validator(min_value=0)

quantity = Validator(min_value=0, max_value=1000)


def __init__(self, name, price, quantity):

self.name = name

self.price = price

self.quantity = quantity



p = Product("Книга", 500, 10)

p.price = 600 # OK

p.quantity = 500 # OK


# p.price = -100 # ValueError: price должно быть = 0

# p.quantity = 2000 # ValueError: quantity должно быть


Дескрипторы в самом Python

property — это дескриптор:

class Circle:

def __init__(self, radius):

self._radius = radius


@property

def radius(self):

return self._radius


@radius.setter

def radius(self, value):

if value

raise ValueError("Радиус не может быть отрицательным")

self._radius = value


Под капотом property — это data-дескриптор, реализующий __get__, __set__, __delete__.

@classmethod и @staticmethod — тоже дескрипторы!

Они реализуют __get__, чтобы возвращать связанные или несвязанные методы.

Data vs Non-data дескрипторы: пример

class NonDataDesc:

def __get__(self, instance, owner):

return "из дескриптора"


class DataDesc:

def __get__(self, instance, owner):

return "из data-дескриптора"

def __set__(self, instance, value):

pass


class MyClass:

non_data = NonDataDesc()

data = DataDesc()


obj = MyClass()


# Non-data дескриптор

print(obj.non_data) # "из дескриптора"

obj.__dict__["non_data"] = "из __dict__"

print(obj.non_data) # "из __dict__" __dict__ перекрывает!


# Data дескриптор

print(obj.data) # "из data-дескриптора"

obj.__dict__["data"] = "из __dict__"

print(obj.data) # "из data-дескриптора" дескриптор перекрывает!


Когда использовать дескрипторы?


Ситуация

Пример

Валидация атрибутов

Проверка типов, диапазонов

Ленивые вычисления

Вычисление значения при первом обращении

Логирование

Отслеживание доступа к атрибутам

Кэширование

Сохранение результатов вычислений

Автоматизация

Повторяющаяся логика для нескольких атрибутов

Создание своих property-подобных механизмов

Кастомные геттеры/сеттеры

Преимущества дескрипторов

  1. Переиспользование — один дескриптор можно применить к множеству атрибутов

  2. Чистый код — логика валидации вынесена из класса

  3. Гибкость — полный контроль над чтением/записью/удалением

  4. Производительность — быстрее, чем __getattr__/__setattr__

  5. Основа языка — понимание дескрипторов = понимание Python

Заключение

  1. Дескриптор — объект, управляющий доступом к атрибутам через __get__, __set__, __delete__.

  2. Data-дескриптор (с __set__) имеет приоритет над __dict__ экземпляра.

  3. Non-data-дескриптор (только __get__) уступает __dict__.

  4. Дескрипторы лежат в основе property, classmethod, staticmethod.

  5. Они идеальны для валидации, логирования, ленивых вычислений.

  6. Понимание дескрипторов — ключ к глубокому пониманию Python.

Освоив протокол дескриптора, вы получаете доступ к одному из самых мощных механизмов Python — инструменту, на котором построены многие встроенные возможности языка. Это уровень продвинутого разработчика, понимающего, как работает Python изнутри.