Задача "Дескриптор для отслеживания изменения значения" на Python
Задача 4:
Напишите дескриптор, который будет отслеживать изменения значения атрибута. При каждом изменении нужно сохранять старое значение в список изменений.
Пример использования:
class ChangeTracker:
pass
class Product:
price = ChangeTracker()
p = Product()
p.price = 100 # первое значение
p.price = 120 # второе значение
p.price = 150 # третье значение
# Список изменений: [100, 120]
Почему мой код вызывает ошибку?
class ChangeTracker:
def __set_name__(self, owner, name):
self.name = "__" + name
self.changes = []
def __get__(self, instance, owner):
return getattr(instance, self.name)
def __set__(self, instance, value):
self.changes.append(value)
setattr(instance, self.name, value)
def get_changes(self):
return self.changes
class Product:
price = ChangeTracker()
def __init__(self, price) -> None:
self.price = price
# Метод для получения изменений
def get_price_changes(self):
return Product.price.get_changes() # Доступ через класс, а не через self.price
# Пример использования
p = Product(90)
p.price = 100 # первое изменение
p.price = 120 # второе изменение
print(p.price)
p.price = 150 # третье изменение
print(p.price)
# Получаем список изменений
# print(p.get_price_changes()) # Список изменений: [90,100, 120]
ошибка:
Traceback (most recent call last):
File "d:\обучение\stepik 28\tz.py", line 179, in <module>
print(p.get_price_changes()) # Список изменений: [90,100, 120]
^^^^^^^^^^^^^^^^^^^^^
File "d:\обучение\stepik 28\tz.py", line 167, in get_price_changes
return Product.price.get_changes() # Доступ через класс, а не через self.price
^^^^^^^^^^^^^
File "d:\обучение\stepik 28\tz.py", line 149, in __get__
return getattr(instance, self.name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
AttributeError: 'NoneType' object has no attribute '__price'
Ответы (1 шт):
Автор решения: Alex Titov
→ Ссылка
См. про аргументы __get__
в доке
def __get__(self, instance, owner):
return self if instance is None else getattr(instance, self.name)