Questa sezione illustrerà le regole di coercizione. Man mano che il linguaggio si è evoluto, è diventato più difficile documentarle con esattezza; non è il massimo spiegare che cosa fa una versione di una particolare implementazione. In Python 3.0, le regole di coercizione non verranno più supportate.
Se l'operando sinistro dell'operatore % è una stringa o un oggetto Unicode non viene applicata nessuna coercizione, ma vengono invocate le operazioni di formattazione stringa.
Non è più raccomandabile definire un'operazione con regole coercitive. Le operazioni compiute in modalità mista sui tipi, che non determinano una coercizione, passano all'operazione l'argomento iniziale.
Le classi di nuovo stile (quelle che derivano dalla classe object) come risposta ad un operatore binario, non invocheranno mai il metodo __coerce__(); __coerce__() viene invocato solamente quando si richiama la funzione built-in coerce().
Nella maggioranza dei casi, un operatore che restituisce
NotImplemented
viene trattato come se non sia stato
implementato per niente.
Sotto, __op__() e __rop__() vengono impiegati per
mostrare l'uso dei dei metodi generici corrispondenti ad un operatore;
__iop__ viene usato per il corrispondente operatore adatto.
Per esempio, per l'operatore `+
', __add__() e
__radd__() vengono utilizzati per le varianti sinistra e
destra dell'operatore binario e __iadd__ per la variante
appropriata.
Per oggetti x e y, viene testato per prima
x.__op__(y)
. Se non è supportato oppure
restituisce NotImplemented
, continua con
y.__rop__(x)
. Se anche questo non è implementato o
restituisce NotImplemented
, viene sollevata l'eccezione
TypeError. Ma si vedano le seguenti eccezioni:
Eccezioni riguardanti l'elemento precedente: se l'operando sinistro è un'istanza di un tipo built-in o una classe di nuovo stile, e l'operando destro è un'istanza di una speciale sottoclasse di quel tipo di classe, viene testato il metodo __rop__() dell'operando destro prima del metodo __op__() dell'operando sinistro. Questo avviene affinché una sottoclasse possa completamente sovrascrivere gli operatori binari. Altrimenti, il metodo __op__ dell'operando sinistro accetta sempre l'operando destro: quando viene attesa un'istanza di una data classe, viene sempre accettata anche un'istanza di una sua sottoclasse.
Non appena un operando specifica una coercizione, questa viene chiamata prima che il metodo __op__() oppure __rop__(), relativo al suo tipo venga chiamato. Se tale coercizione restituisce un oggetto di tipo differente dall'operando le cui regole coercitive siano state invocate, parte del processo viene rieseguito usando il nuovo oggetto.
Quando viene usato un operatore locale (come `+=
'), se
l'operando sinistro supporta __iop__(), questo metodo viene
invocato senza alcuna coercizione. Quando il processo di calcolo
ritorna a __op__() e/o __rop__(), si applicano le
normali regole coercitive.
Quando in x+
y, x è una sequenza che supporta
la concatenazione di sequenze, viene appunto invocata la
concatenazione di sequenze.
QUando in x*
y, un operatore è una sequenza che
supporta la ripetizione di sequenze, e l'altro è costituito da un
intero (int o long), viene invocata la ripetizione di
sequenze.
I confronti ricchi (implementati dai metodi __eq__() e via dicendo) non usano mai la coercizione. Il confronto a tre (supportato da __cmp__()) utilizza le regole coercitive alle stesse condizioni di come sono impiegate nelle operazioni binarie.
Nell'attuale implementazione, i tipi numerici built-in int, long e float non usano la coercizione; i tipi numerici complessi, complex, comunque la utilizzano. La differenza appare evidente quando si sottoclassano questi tipi. Eccezionalmente, il tipo numerico complesso, complex, può essere determinato in modo da evitare le regole coercitive. Tutti questi tipi implementano un metodo __coerce__(), per l'uso della funzione built-in coerce().