在 Python (2.7) 中,为什么 os.remove 与 os.unlink 不同? [英] In Python (2.7), why is os.remove not identical to os.unlink?
问题描述
这是为什么?os.unlink 不应该是 os.remove 的别名吗?
要回答这个问题,我们必须深入了解 Python 解释器的工作原理.在其他 Python 实现中可能会有所不同.
首先让我们从定义 os.remove
和 os.unlink
函数的位置开始.在 Modules/posixmodule.c 中,它们注册为:
{"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},{删除",posix_unlink,METH_VARARGS,posix_remove__doc__},
请注意,函数指针都指向 ml_meth
成员中的 posix_unlink
.
对于方法对象,==
相等运算符由 meth_richcompare(...)
在 对象/methodobject.c.
它包含这个逻辑,这解释了为什么 ==
运算符返回 True
.
a = (PyCFunctionObject *)self;b = (PyCFunctionObject *)other;eq = a->m_self == b->m_self;如果(等式)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
.在这种情况下,函数指针就是内容.
>>> 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
Why is that? Isn't os.unlink supposed to be an alias of os.remove?
To answer this question we have to dive a bit into the details of how the python interpreter works. It might be different in other python implementations.
First let's start where the os.remove
and os.unlink
functions are defined. In Modules/posixmodule.c they are registered as:
{"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
{"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
Note that the function pointers both point to posix_unlink
in their ml_meth
member.
For method objects, the ==
equality operator is implemented by meth_richcompare(...)
in Objects/methodobject.c.
It contains this logic, which explains why the ==
operator returns 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;
For built-in functions m_self
is NULL
so eq
starts out true
. We then compare the function pointers in ml_meth
(the same posix_unlink
referenced from the struct above) and since they match eq
remains true
. The end result is that python returns True
.
The is
operator is simpler and stricter. The is
operator only compares the PyCFunctionObj*
pointers. They will be different -- they came from different structs and are distinct objects, so the is
operator will return False
.
The rationale is likely that they are separate functions objects (recall their docstrings are different) but they point to the same implementation, so the difference in behavior between is
and ==
is justifiable.
is
brings a stronger guarantee, and is meant to be fast and cheap (a pointer comparison, essentially). The ==
operator inspects the object and returns True
when its content matches. In this context, the function pointer is the content.
这篇关于在 Python (2.7) 中,为什么 os.remove 与 os.unlink 不同?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!