Data Descriptor
from time import time
class Epoch:
def __get__(self, instance, owner):
print(f"Self object {self}")
print(f"Instance object {instance}")
print(f"Owner object {owner}")
return int(time())
class MyTime:
epoch = Epoch()
m = MyTime()
12345678910111213141516При вызове epoch через экземпляр m класса MyTime:
>>> m.epoch
Self object <__main__.Epoch object at 0x7fcd70bf6950>
Instance object <__main__.MyTime object at 0x7fcd70bf6ad0>
Owner object <class '__main__.MyTime'>
1686562054
1234567В Self был передан сам объект класса Epoch (сам дескриптор - экземпляр дескриптора)
В Instance объект из которого произошло обращение к дескриптору (экземпляр класса MyTime)
В Owner объект, класс собственник MyTime
Мы можем обращаться к атрибуту класса (epoch) через сам класс (MyTime):
В Instance не был передан никакой объект - т.к. обращение произошло через класс (MyTime) а не через экземпляр (m)
Это напоминает работу @property:
Возвращать сам экземпляр класса (дескриптора), если обращение произошло через класс
Возвращать значение свойств, если обращение произошло через экземпляр
[!warning] Особенность хранения данных в дескипторах Нельзя хранить данные в экземпляре дескриптора (реализующих методы get, set, delete), т.к. они делят общее состояние с экземплярами класса.
Имеется ввиду со стандартной реализацией set.
Для хранения данных в дескипторе можно определить словарь (dict) в инициализации и в методе __set__() передавать в него значение по ключу
Но такой вариант реализации допустит утечку памяти - при пересохранении значений будут сохраняться ссылки на значения.
Чтобы предотвратить утечку памяти, следует использовать слабые ссылки (weakref).
Для подсчета ссылок, можно использовать:
Либо с библиотекой ctypes
Описание утечки памяти из примера выше:
Last updated
Was this helpful?