>>> import sys
>>> sys.version
'2.7.3 (default, Mar 13 2014, 11:03:55) \n[GCC 4.7.2]'
>>> import os
>>> os.remove is os.unlink
False
>>> os.remove == os.unlink
True
Почему? Не означает ли os.unlink быть псевдонимом os.remove?
>>> import sys
>>> sys.version
'2.7.3 (default, Mar 13 2014, 11:03:55) \n[GCC 4.7.2]'
>>> import os
>>> os.remove is os.unlink
False
>>> os.remove == os.unlink
True
Почему? Не означает ли os.unlink быть псевдонимом os.remove?
Чтобы ответить на этот вопрос, нам нужно немного погрузиться в детали того, как работает интерпретатор python. Это может быть другим в других реализациях python.
Сначала начните, где определены функции os.remove
и os.unlink
. В Modules/posixmodule.c они зарегистрированы как:
{"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
{"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
Обратите внимание, что указатели функции указывают на posix_unlink
в своем члене ml_meth
.
Для объектов метода оператор равенства ==
реализуется meth_richcompare(...)
в Objects/methodobject.c.
Он содержит эту логику, которая объясняет, почему оператор ==
возвращает True
.
a = (PyCFunctionObject *)self;
b = (PyCFunctionObject *)other;
eq = a->m_self == b->m_self;
if (eq)
eq = a->m_ml->ml_meth == b->m_ml->ml_meth;
Для встроенных функций m_self
есть NULL
, поэтому eq
запускается True
. Затем мы сравниваем указатели на функции в ml_meth
(те же posix_unlink
, на которые ссылается ссылка из вышеприведенной структуры), и поскольку они соответствуют eq
, остается True
. Конечным результатом является то, что python возвращает True
.
Оператор is
проще и строже. Оператор is
сравнивает только указатели PyCFunctionObj*
. Они будут разными: они поступают из разных структур и представляют собой разные объекты, поэтому оператор is
вернет False
.
Обоснование, вероятно, состоит в том, что они являются отдельными объектами функций (напомните, что их докстедры различны), но они указывают на одну и ту же реализацию, поэтому разница в поведении между is
и ==
оправдана.
is
приносит более сильную гарантию и подразумевает быструю и дешевую (сравнение указателей, по существу). Оператор ==
проверяет объект и возвращает True
, когда его содержимое совпадает. В этом контексте указателем функции является содержимое.