10
>>> 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 的别名吗?

4

1 回答 1

16

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

首先让我们从定义os.removeandos.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内容匹配时返回。在这种情况下,函数指针就是内容。

于 2016-05-21T11:20:15.380 回答