Потратил 2.5 часа на 20-минутную тему из видео, но выжимку даю за 3 минуты чтения. Сколько раз пересматривал и пытался понять? - ДА
О чем тут вообще речь:
Мы создаем еще один другой класс, чтобы в нашем исходном классе его использовать и писать меньше одинакового кода в нем, но при этом чтобы он работал так же как и раньше. Лучше это или нет - судить вам. Речь про гетеры и сетеры (+"делеторы😁) Я бы сказал, просто вынос логики в другой класс. Так ли?🤔 А это даже наследование не проходилось еще🫠🫠🫠 Если не понятно о чем я - смотрите пример:
Задача: Класс для 3D точек в пространстве. Создать в нем приватные координаты и методы чтобы с ними можно было взаимодействовать.
❌ БЫЛО (20+ строк кода):
class Point3D:
def __init__(self, x, y, z):
self._x = x
self._y = y
self._z = z
@staticmethod
def verify_coord(coord):
if type(coord) != int:
raise TypeError('Координата должна быть целым числом')
@property
def x(self):
return self._x
@x.setter
def x(self, coord):
self.verify_coord(coord)
self._x = coord
# и так еще 2 раза для y, z... а если их больше будет?!
⚡️ СТАЛО (магия дескрипторов):
class Integer:
@staticmethod
def verify_coord(coord):
if type(coord) != int:
raise TypeError('Координата должна быть целым числом')
def __set_name__(self, owner, name): # а это что еще за зверь?!
self.name = '_' + name
# еще один вариант установки имени, как в property, аналог
# self.__name = f'_{owner.__name__}__{name}'
def __get__(self, instance, owner): # геттер
return getattr(instance, self.name)
# return instance.__dict__[self.name] # другой способ для примера
def __set__(self, instance, value): # сеттер
self.verify_coord(value)
setattr(instance, self.name, value)
# instance.__dict__[self.name] = value # другой способ для примера
Теперь класс Point3D выглядит таким образом, гораздо лучше ж?
class Point3D:
x = Integer()
y = Integer()
z = Integer()
def __init__(self, x, y ,z):
self.x = x
self.y = y
self.z = z
💡 СУТЬ ПРОСТЫМИ СЛОВАМИ:
Дескрипторы = "фабрики property". Один раз написал логику - используй для любого количества атрибутов!
🎯 КОГДА ПРИМЕНЯТЬ:
•Больше 2 property с одинаковой логикой
• Хочешь сделать код чище
• Устал от копипасты
🤔 СПОЙЛЕР ДЛЯ ЛЮБОЗНАТЕЛЬНЫХ:
А знаете, что дескрипторы бывают двух типов?
Non-data vs Data дескрипторы...
Как думаете, в чем между ними разница?
И какой тип мы использовали в примере выше? 🤔
💬 Пишите ваши версии в комментах!
А вы сталкивались с дескрипторами в работе?
Или предпочитаете "старый добрый" copy-paste?
Делитесь опытом - интересно, кому это реально пригодилось!
P.S. Если тема зашла - лайкните, допишу пару моментов с тонкостями! Или не допишу, как хотите😈