>>> 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的别名?
答案 0 :(得分:15)
要回答这个问题,我们必须深入了解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
。
对于方法对象,==
等式运算符由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_self
为NULL
,因此eq
开始true
。然后,我们比较ml_meth
中的函数指针(从上面的结构引用的posix_unlink
),因为它们匹配eq
仍然是true
。最终结果是python返回True
。
is
运算符更简单,更严格。 is
运算符仅比较PyCFunctionObj*
指针。它们将是不同的 - 它们来自不同的结构并且是不同的对象,因此is
运算符将返回False
。
理由很可能是它们是单独的函数对象(回想一下它们的文档字符串是不同的)但它们指向相同的实现,因此is
和==
之间的行为差异是合理的。
is
带来更强大的保证,并且意味着快速而便宜(基本上是指针比较)。 ==
运算符检查对象,并在其内容匹配时返回True
。在此上下文中,函数指针是内容。