Um diese Frage zu beantworten, müssen wir ein wenig in die Einzelheiten des Python-Interpreters eintauchen. In anderen Python-Implementierungen kann dies anders sein.
Zuerst starten wir, wo die Funktionen os.remove
und os.unlink
definiert sind. In Modules/posixmodule.c sie sind angemeldet als:
{"unlink", posix_unlink, METH_VARARGS, posix_unlink__doc__},
{"remove", posix_unlink, METH_VARARGS, posix_remove__doc__},
Beachten Sie, dass die Funktionszeiger beide auf posix_unlink
in ihrem ml_meth
Mitglied.
Bei Methodenobjekten wird der ==
Gleichheitsoperator von meth_richcompare(...)
in Objects/methodobject.c implementiert.
Es enthält diese Logik, die erklärt, warum der Operator ==
True
zurückgibt.
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;
Für integrierte Funktionen m_self
ist NULL
so eq
true
beginnt. Wir vergleichen dann die Funktionszeiger in ml_meth
(dasselbe posix_unlink
, das von der Struktur oben verwiesen wird), und da sie übereinstimmen, bleibt true
. Das Endergebnis ist, dass Python True
zurückgibt.
Der Operator is
ist einfacher und strenger. Der Operator is
vergleicht nur die Zeiger PyCFunctionObj*
. Sie werden anders sein - sie kommen aus verschiedenen Strukturen und sind unterschiedliche Objekte, so dass der Operator is
False
zurückgibt.
Der Grund ist wahrscheinlich, dass sie getrennte Funktionen Objekte sind (erinnern an ihre Docstrings verschieden sind), aber sie weisen auf die gleiche Umsetzung, so dass der Unterschied im Verhalten zwischen is
und ==
ist vertretbar.
is
bringt eine stärkere Garantie, und soll schnell und billig sein (ein Zeiger Vergleich, im Wesentlichen). Der Operator ==
prüft das Objekt und gibt True
zurück, wenn der Inhalt übereinstimmt. In diesem Kontext ist der Funktionszeiger der Inhalt.