【问题标题】:In Python (2.7), why is os.remove not identical to os.unlink?在 Python (2.7) 中,为什么 os.remove 与 os.unlink 不一样?
【发布时间】:2015-01-30 04:59:32
【问题描述】:
>>> 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 的别名吗?

【问题讨论】:

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


    【解决方案1】:

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

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

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

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

    对于方法对象,== 相等运算符由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_selfNULL 所以eq 开始于true。然后我们比较ml_meth 中的函数指针(与上面的结构体引用的posix_unlink 相同),因为它们匹配eq,所以仍然是true。最终结果是python返回True

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

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

    is 带来了更强的保证,并且意味着快速和便宜(本质上是指针比较)。 == 运算符检查对象并在其内容匹配时返回 True。在这种情况下,函数指针就是内容。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-12-25
      • 2011-11-15
      • 1970-01-01
      • 2015-02-27
      • 2014-06-19
      • 2021-01-11
      相关资源
      最近更新 更多