Какова цель экземпляра и владельца в дескрипторах Python? - PullRequest
1 голос
/ 08 марта 2019

Я пытаюсь понять дескрипторы в Python.Кажется, я не могу понять, что такое экземпляр и владелец в методе дескриптора:

object.__get__(self, instance, owner)

Теперь я прочитал документацию , в которой говорится:

владелец всегда является классом владельца, а экземпляр - это экземпляр, к которому был получен доступ к атрибуту, или None, когда к атрибуту обращаются через владельца.

К сожалению, у меня возникли проблемыпонимание того, что это значит.Относится ли владелец к самому классу?Объект класса?Тогда какова цель передачи ему экземпляра?

Ответы [ 3 ]

0 голосов
/ 08 марта 2019

Отношения могут быть проиллюстрированы этим кодом:

class DescriptorClass:
    def __get__(self, instance, owner):
        return self, instance, owner

class OwnerClass:
    descr = DescriptorClass()

ownerinstance = OwnerClass()

self, instance, owner = ownerinstance.descr

assert self is OwnerClass.__dict__['descr']
assert instance is ownerinstance
assert owner is OwnerClass

self, instance, owner = OwnerClass.descr
assert instance is None
0 голосов
/ 08 марта 2019

Учитывайте это

 __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')
0 голосов
/ 08 марта 2019

Относится ли владелец к самому классу?

Да.

Объект класса?

Это то же самое.

Тогда какова цель передачи ему экземпляра?

Как дескриптор может получить доступ к экземпляру, на котором он был найден?Например, если вы используете встроенный тип property, он работает, сохраняя функции доступа и вызывая эти функции.Эти функции ожидают текущий экземпляр в качестве первого аргумента (канонически называемый «self»).Если дескриптор не получает текущий экземпляр, он, очевидно, не может передать его аксессору.

...