В Python (2.7), почему os.remove не идентичен os.unlink?

>>> 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?

Ответ 1

Чтобы ответить на этот вопрос, нам нужно немного погрузиться в детали того, как работает интерпретатор 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, когда его содержимое совпадает. В этом контексте указателем функции является содержимое.