2014-12-02 9 views

Odpowiedz

14

Aby odpowiedzieć na to pytanie, musimy trochę zastanowić się nad tym, jak działa interpreter python. Może się różnić w innych implementacjach Pythona.

Najpierw zacznijmy od zdefiniowania funkcji os.remove i os.unlink. W Modules/posixmodule.c są zarejestrowani jako:

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

Uwaga, że ​​wskaźniki funkcyjne zarówno punkt posix_unlink w ich ml_meth członka.

Dla obiektów metodowych operator równości == jest zaimplementowany przez meth_richcompare(...) w Objects/methodobject.c.

Zawiera tę logikę, która wyjaśnia, dlaczego operator zwraca 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; 

Dla wbudowanych funkcji m_self jest NULL tak eq zaczyna się true. Następnie porównujemy wskaźniki funkcji w ml_meth (ten sam posix_unlink, do którego odwołuje się powyższa struktura), a ponieważ pasują one do eq pozostaje true. Końcowy wynik jest taki, że pyton zwraca True.

Operator is jest prostszy i bardziej rygorystyczny. Operator is porównuje tylko wskaźniki: PyCFunctionObj*. Będą różne - pochodzą z różnych struktur i są odrębnymi obiektami, więc operator is zwróci False.

Uzasadnieniem jest to, że są one oddzielnymi obiektami funkcji (przypominają, że ich argumenty są różne), ale wskazują na tę samą implementację, więc różnica w zachowaniu między is i == jest uzasadniona.

is daje silniejszą gwarancję i ma być szybki i tani (w zasadzie porównanie wskaźnika). Operator == sprawdza obiekt i zwraca True, gdy jego zawartość jest zgodna. W tym kontekście wskaźnik funkcji jest treścią.