Скажем, у меня есть координата класс, который служит дескриптором:
Код: Выделить всё
class Coordinate:
def __set_name__(self, owner, name):
self._name = name
def __get__(self, instance, owner):
return instance.__dict__[self._name]
def __set__(self, instance, value):
try:
instance.__dict__[self._name] = float(value)
except ValueError:
raise ValueError(f'"{self.__set_name__}" must be a number') from None
Код: Выделить всё
class Point:
x = Coordinate()
y = Coordinate()
def __init__(self, x, y):
self.x = x
self.y = y
Код: Выделить всё
point1 = Point(12,5)
Код: Выделить всё
print(point1.x)
Я знаю, что если я попробую это, ничего не получится:
Код: Выделить всё
print(point1.x.__get__(Point))
- self: будет point1.x, экземпляр координатора.
- экземпляр: будет мой point1, экземпляр Point.
- владелец: будет класс Point.
Код: Выделить всё
x.__get__()Тогда, поскольку у меня есть point1.x.__get()
x будет моим первым аргументом, а point1 будет моим вторым аргументом.
И наличие Точки, переданный в скобках, выполнил то, что я хотел, но он все равно не будет работать, потому что, хотя метод get возвращает 12.0, Python теперь попытается вызвать get метод в float (12.0), возвращенный моим ручным вызовом get, и это вызовет исключение.
Код: Выделить всё
'float' object has no attribute '__get__'
Код: Выделить всё
print(Point.x.__get__(Point))
- self : это будет Point.x, экземпляр координаты, объявленный в классе Point.
- экземпляр: это будет ссылка на сам мой класс Point.
- владелец: также будет ссылкой на сам класс Point.
Почему это происходит? Почему он не заполняется ссылкой на Point, если все остальные аргументы передаются правильно? (Оба аргументы self и Owner имеют ожидаемые значения).
Подробнее здесь: https://stackoverflow.com/questions/787 ... -in-python