Внутреннее устройство метода __get__ в PythonPython

Программы на Python
Anonymous
Внутреннее устройство метода __get__ в Python

Сообщение Anonymous »

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

Код: Выделить всё

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
И класс Point, который будет иметь 2 свойства, которые являются координатами:

Код: Выделить всё

class Point:
x = Coordinate()
y = Coordinate()

def __init__(self, x, y):
self.x = x
self.y = y
Предположим, я создаю новую точку в своем основном коде:

Код: Выделить всё

point1 = Point(12,5)
Я знаю, что если я попытаюсь это сделать:

Код: Выделить всё

print(point1.x)
Я получу это в консоли: 12.0
Я знаю, что если я попробую это, ничего не получится:

Код: Выделить всё

print(point1.x.__get__(Point))
Мой метод get будет вызываться со следующими параметрами:
  • self: будет point1.x, экземпляр координатора.
  • экземпляр: будет мой point1, экземпляр Point.
  • владелец: будет класс Point.
Все это из-за порядка аргументы. Так как у меня:

Код: Выделить всё

x.__get__()
x будет моим первым аргументом.
Тогда, поскольку у меня есть 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))
Вместо того, чтобы заполнять аргументы метода get следующим образом:
  • self : это будет Point.x, экземпляр координаты, объявленный в классе Point.
  • экземпляр: это будет ссылка на сам мой класс Point.
  • владелец: также будет ссылкой на сам класс Point.
В аргументе экземпляр указывается значение None.
Почему это происходит? Почему он не заполняется ссылкой на Point, если все остальные аргументы передаются правильно? (Оба аргументы self и Owner имеют ожидаемые значения).

Подробнее здесь: https://stackoverflow.com/questions/787 ... -in-python

Вернуться в «Python»