Учитывайте это
__get__(self, instance, owner):
owner
- это относится к классу, в котором был создан объект дескриптора, помните, что объекты дескриптора определены на уровне класса.
instance
- этоотносится к объекту класса owner
, в котором вы определили объект дескриптора.
Цель передачи instance
методу __get__
дескриптора состоит в том, чтобы убедиться, что мы знаем и идентифицируем, из какихобъект класса owner
, к которому вы обращаетесь к экземпляру дескриптора.
Поскольку объекты дескриптора создаются на уровне класса, поэтому наивная реализация самого класса дескриптора может привести к наличию нескольких объектов owner
класс, переопределяющий значение экземпляра дескриптора.Вот пример такого кода
def __get__(self, instance, owner):
return self.data
def __set__(self, instance, data):
if value < 1:
raise Exception("Negative or zero is not allowed")
else:
self.data = value
Так что в приведенном выше примере значение data
хранится только внутри экземпляра дескриптора, и этот код будет иметь серьезные побочные эффекты, если вы создаете несколько объектовкласс owner
и, скажем, эти объекты устанавливают значение data
.
Так что для решения такой проблемы вам нужно сохранить значение data
в __dict__
из instance
но как бы вы это сделали, если у вас нет доступа к instance
в самом классе дескриптора ??Так что, по моему опыту, это основная цель иметь instance
в классе дескриптора.В качестве справочной информации для решения вышеупомянутой проблемы и использования instance
здесь используется код
class DataDescriptor(object):
def __init__(self, attribute):
self.default = 100
self.attribute = attribute
def __get__(self, instance, owner):
print('Getting the value of', self.attribute,
'__get__ of Data descriptor invoked')
return instance.__dict__.get(self.attribute, self.default)
def __set__(self, instance, value=200):
if value > 0:
print('__set__ of Data descriptor invoked')
instance.__dict__[self.attribute] = value
else:
sys.exit('Negative value not allowed')