Задать вопрос
sswwssww
@sswwssww

Почему при присваивании вызывается __set__?

Есть следующий код:
class NonNegative:
    def __init__(self, name):
        self.name = name

    def __get__(self, instance, owner):
        return instance.__dict__[self.name]

    def __set__(self, instance, value):
        if value < 0:
            raise ValueError('Cannot be negative.')
        instance.__dict__[self.name] = value

class Order:
    price = NonNegative('price')

    def __init__(self, name, price, quantity):
        self._name = name
        self.price = price

apple_order = Order('apple', 1, 10)
apple_order.price = -10

-смотрю через дабаггер, когда выполняется строчка "self.price = price" идет переход к "__set__" класса "NonNegative". Почему такое происходит? Мы же никак неиспользуем инстанс "price" у "NonNegative". На сколько я понимаю "self.price" в self.price = price это просто поле инстанса класса "Order".
  • Вопрос задан
  • 190 просмотров
Подписаться 2 Простой Комментировать
Решения вопроса 1
sswwssww
@sswwssww Автор вопроса
Т.е. видимо, когда выполняется "self.price", Python сначала смотрит (1) есть ли такое поле у инстанса, если нет то (2) ищет это поле у класса(а это поле у нас есть и является дескриптором), если и там нет то (3) оно просто создается. В моем случае остановка происходит на втором пункте.
Вся суть в том, что через self мы можем обращаться к полям класса.

javedimka: "В методе __ini__ self.price уже является дескриптором, т.к. self.price определён на уровне класса, ты не записываешь туда 1, ты вызываешь метод __set__ дескриптора при инициализации. Попробуй -10 передать при инциализации, сразу всё понятно станет"
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
@deliro
Fluent python, глава про дескрипторы.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы