在Python(2.7)中,为什么os.remove与os.unlink不相同?

时间:2014-12-02 02:50:25

标签: python python-2.7 object-identity object-equality

>>> 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 个答案:

答案 0 :(得分:15)

要回答这个问题,我们必须深入了解python解释器的工作原理。在其他python实现中可能会有所不同。

首先让我们从定义os.removeos.unlink函数开始。在Modules/posixmodule.c中,他们注册为:

{"unlink",          posix_unlink, METH_VARARGS, posix_unlink__doc__},
{"remove",          posix_unlink, METH_VARARGS, posix_remove__doc__},

请注意,函数指针都指向posix_unlink成员中的ml_meth

对于方法对象,==等式运算符由Objects/methodobject.c中的meth_richcompare(...)实现。

它包含此逻辑,解释了==运算符返回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_selfNULL,因此eq开始true。然后,我们比较ml_meth中的函数指针(从上面的结构引用的posix_unlink),因为它们匹配eq仍然是true。最终结果是python返回True

is运算符更简单,更严格。 is运算符仅比较PyCFunctionObj*指针。它们将是不同的 - 它们来自不同的结构并且是不同的对象,因此is运算符将返回False

理由很可能是它们是单独的函数对象(回想一下它们的文档字符串是不同的)但它们指向相同的实现,因此is==之间的行为差​​异是合理的。

is带来更强大的保证,并且意味着快速而便宜(基本上是指针比较)。 ==运算符检查对象,并在其内容匹配时返回True。在此上下文中,函数指针是内容。