2014-12-02 12 views

risposta

14

Per rispondere a questa domanda dobbiamo immergerci un po 'nei dettagli di come funziona l'interprete python. Potrebbe essere diverso in altre implementazioni Python.

Iniziamo innanzitutto da dove sono definite le funzioni os.remove e os.unlink. In Modules/posixmodule.c sono registrati come:

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

Nota che i puntatori a funzione sia punto di posix_unlink nella loro ml_meth membro.

Per gli oggetti metodo, l'operatore di uguaglianza == è implementato da in Objects/methodobject.c.

Contiene questa logica, che spiega perché l'operatore == restituisce 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; 

Per le funzioni incorporate m_self è NULL così eq inizia true. Quindi confrontiamo i puntatori di funzione in ml_meth (lo stesso posix_unlink a cui si fa riferimento dalla struttura in alto) e poiché corrispondono a eq rimane true. Il risultato finale è che python restituisce True.

L'operatore is è più semplice e più rigido. L'operatore is confronta solo i puntatori PyCFunctionObj*. Saranno diversi: provengono da diverse strutture e sono oggetti distinti, pertanto l'operatore is restituirà False.

La logica è probabile che siano oggetti di funzioni separate (richiamare le loro docstring sono diversi) ma indicano la stessa implementazione, quindi la differenza di comportamento tra is e == è giustificabile.

is porta una garanzia più forte, ed è pensato per essere veloce ed economico (un confronto puntatore, in sostanza). L'operatore == ispeziona l'oggetto e restituisce True quando il suo contenuto corrisponde. In questo contesto, il puntatore della funzione è il contenuto.