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

Другие вопросы по тегам