Почему первый результат False
, если он не был True
?
>>> from collections import OrderedDict
>>> OrderedDict.__repr__ is OrderedDict.__repr__
False
>>> dict.__repr__ is dict.__repr__
True
Почему первый результат False
, если он не был True
?
>>> from collections import OrderedDict
>>> OrderedDict.__repr__ is OrderedDict.__repr__
False
>>> dict.__repr__ is dict.__repr__
True
Для пользовательских функций в Python 2 создаются по запросу безграничные и связанные методы, используя протокол дескриптора; OrderedDict.__repr__
- такой объект метода, поскольку завернутая функция реализована как функция pure-Python.
Протокол дескриптора вызовет метод __get__
для объектов, которые его поддерживают, поэтому __repr__.__get__()
вызывается всякий раз, когда вы пытаетесь получить доступ к OrderedDict.__repr__
; для классов None
(нет экземпляра) и сам объект класса. Поскольку вы получаете новый объект метода каждый раз при вызове метода __get__
, is
терпит неудачу. Это не тот же объект метода.
dict.__repr__
не является настраиваемой функцией Python, а функцией C и ее дескриптором __get__
по существу просто возвращает self
при доступе к классу. Доступ к атрибуту дает один и тот же объект каждый раз, поэтому is
работает:
>>> dict.__repr__.__get__(None, dict) is dict.__repr__ # None means no instance
True
Методы имеют атрибут __func__
, ссылающийся на обернутую функцию, используют это для проверки подлинности:
>>> OrderedDict.__repr__
<unbound method OrderedDict.__repr__>
>>> OrderedDict.__repr__.__func__
<function __repr__ at 0x102c2f1b8>
>>> OrderedDict.__repr__.__func__.__get__(None, OrderedDict)
<unbound method OrderedDict.__repr__>
>>> OrderedDict.__repr__.__func__ is OrderedDict.__repr__.__func__
True
Python 3 устраняет несвязанные методы, function.__get__(None, classobj)
возвращает сам объект функции (поэтому он ведет себя как dict.__repr__
). Но вы увидите то же поведение с связанными методами, методами, полученными из экземпляра.
Два OrderedDict.__repr__
не привязаны к одному и тому же объекту. Если вы попытаетесь:
OrderedDict.__repr__ == OrderedDict.__repr__
вы увидите, что они имеют одинаковое значение.