Задать вопрос

Не пойму поведение type с weakref?

Здравствуй, Хабр.

Я всегда был уверен, что в Python для объектов новых классов атрибут x.__class__ и type(x) будут иметь одно и то же значение. Однако если проделать вот такое (проверено с Python 2.7.3 и 3.3.0, а также PyPy 2.0b1):
>>> import weakref
>>> x = set()
>>> y = weakref.proxy(x)
>>> x.__class__, type(x), isinstance(x, set)
(<class 'set'>, <class 'set'>, True)
>>> y.__class__, type(y), isinstance(y, set)
(<class 'set'>, <class 'weakproxy'>, True)
мы увидим, что для weakref.proxyy.__class__ соответствует обернутому типу (полагаю, weakref.proxy просто подменяет атрибут, чтобы мимикрировать под оборачиваемый объект), и даже isinstance распознает в нем set. Но при этом type указывает на его истинный тип — weakproxy. Получается, что type не использует для определения типа аргумента его атрибут __class__. Выходит, что он type пользуется неким «более достоверным» источником для определения типа? Можно ли получить к нему доступ?
  • Вопрос задан
  • 3073 просмотра
Подписаться 4 Оценить Комментировать
Решения вопроса 1
Ivanhoe
@Ivanhoe Автор вопроса
Ответ такой.

Внутри интерпретатора (CPython) каждый Python-объект представлен C-структурой PyObject (файл object.h), в которой одно из полей — ob_type, указатель на структуру _typeobject, котоая определяет «настоящий» тип объекта. type(x) и дескриптор object.__class__ обращаются за типом к этому полю. Но __class__ можно переопределить, что и делает weakref.proxy. При этом type(x) все равно будет продолжать обращаться к ob_type и результат его определения подменить не удастся.
Ответ написан
Комментировать
Пригласить эксперта
Ответы на вопрос 1
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы