Рубрики
Без рубрики

Дескриптор протокол и как ORM использует это?

Что такое дескриптор? (Конечно, приходит некоторое допущенное определение) По официальному питону … Теги с Python.

Дескриптор протокол (2 части серии)

(Конечно, приходит некоторое допущенное определение)

Согласно официальным документам Python3, это то, что они говорят

В целом, дескриптор представляет собой атрибут объекта с «привязчивым поведением», которого доступен атрибут которого был переопределен методами в протоколе дескриптора. Эти методы __get __ (), __set __ () и __delete __ (). Если какой-либо из этих методов определены для объекта, считается дескриптором.

Теперь кажется довольно ясно, что нам нужен класс, и в этом классе нам нужно определить эти методы, и это. Давайте попробуем

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

    def __set__(self, instance, value):
        print("setting the attribute")
        instance.__dict__[self.name] = value

    def __delete__(self, instance):
        del instance.__dict__[self.name]

    def __set_name__(self, owner, name):
        self.name = name

Теперь мы хотим использовать этот дескриптор

class B:
    a = A()
i = B()
print(i.a)
# KeyError: 'a'
i.a = "wysiwyg"
# setting the attribute
print(i.a)
# wysiwyg

(Хорошо, достаточно Chit-Chat, давайте драться, извините, жаль, давайте понять, как мы можем использовать эту концепцию) Так что предположим, что вы хотите подтвердить, прежде чем установить значение или получить значение. Но подождите, есть Getter и Getters, верно? Да, есть, но я поклонник сухого, и я торжественно клянусь, чтобы не повторить, кроме необходимого. Итак, даже если условие одинаковое, вы должны использовать сеттер каждый раз для каждого атрибута.

class CheckString:
    def __set_name__(self, owner, name):
        self.name = name

    def __set__(self, instance, value):
        if isinstance(value, str):
            instance.__dict__[self.name] = value
        else:
            raise ValueError("Value must be string")


class User:
    name = CheckString()
    email = CheckString()

    def __init__(self, name, email):
        self.name = name
        self.email = email

u = User("Sumit", 1)
# ValueError: Value must be string

Теперь, если мы хотим реализовать то же самое с собственностью Как мы бы имели

class User:
    def __init__(self, name, email):
        self._name = name
        self._email = email

    @property
    def email(self):
        return self._email

    @email.setter
    def email(self, value):
        if isinstance(value, str):
            self._email = value
        else:
            raise ValueError("Value must be string")

    @property
    def name(self):
        return self._name

    @name.setter
    def name(self, value):
        if isinstance(value, str):
            self._name = value
        else:
            raise ValueError("Value must be string")

...

u.email = 1
# ValueError: Value must be string

В следующем посте мы постараемся декодировать, как ORM (объектно-реляционное отображение) воспользоваться дескрипторами.

Дескриптор протокол (2 части серии)

Оригинал: “https://dev.to/sroy8091/descriptor-protocol-and-how-django-orm-uses-it-23e6”