[Python] 0 in (False,) // 0 == False

Daniele Varrazzo piro a develer.com
Ven 5 Feb 2010 13:25:26 CET


On Fri, 5 Feb 2010 09:57:44 +0100, Lawrence Oluyede <l.oluyede a gmail.com>
wrote:
> 2010/2/5 Pietro Battiston <toobaz a email.it>:
>> A questo punto, la
>> domanda è, a parità di duck typing, cosa abbia di comodo 0 == False, e
>> l'unica risposta che sono in grado di formulare è "facilità di
>> implementazione".
> 
> Non e` quella l'unica risposta, e` molto comodo avere 0, [], {}, () e
> altri contenitori equivalenti a False.
> Si parla di programmazione all'atto pratico, non per forza di
> comodita` dell'implementatore.

Rispondo a questo msg ma solo perché non saprei a quale appendermi :P

Non confondiamo 2 cose: una è "essere falso in contesto booleano", per cui
"if X:" può andare in un ramo o nell'altro a seconda del valore di
X.__nonzero__(). Un'altra è il fatto che si possa fare True + False
(l'algebra di boole non prevede operatori numerici tipo la somma). Un'altra
ancora è il fatto che True + True faccia 2 (che volendo è un dettaglio
implementativo, volendo è una convenzione che viene dal C). Bene: le due
cose da non confondere sono 3.

1) Il fatto che ci siano diverse cose "testabili come valori di verità" è
molto comodo in python, più ancora di avere True e False (che infatti sono
abbastanza recenti: python 2.3 iirc). Chiedere che if []: non debba essere
possibile ma debba essere necessario fare "if bool([]):" mi sembra fuori
questione (non così per Raffaele Salmaso, quindi non è un gusto
universale... a me piace che sia così).

2) Se Python fosse puristicamente puro, forse bool non implementerebbe la
somma. Ora la implementa semplicemente perché eredita da int, ma se anche
non fosse così l'aritmetica mista (1 + true) sarebbe comunque auspicata
(anche nel "mondo perfetto" evocato da Guido) per cui, o implementando
__add__, o implementando __int__ e quindi lasciandosi sommare dopo una
conversione in un intero, in qualche modo si sarebbe fatto. È come dire "è
sensato che esista una funzione definita dai bool agli int". Se non
esistesse, la gente se la scriverebbe perché farebbe comodo, quindi tanto
vale uniformare il valore di di int(B) per ogni B booleano.

3) Deciso che deve fare un numero, quanto devono valere int(True) e
int(False)? Python usa la convenzione C, dove non ci sono bool, solo
numeri, e 0 è il valore falso (quello che fa prendere il ramo else ad un
if) e 1 è il valore vero (nel senso che !0 = 1, e !!10 = 1, non che esista
una keyword "true"). È un numero sensato perché non é dipendente
dall'implementazione (mentre il risultato del not booleano "~0" lo è) e
perché qualunque rappresentazione numerica plausibile (interi, floating
point, virgola fissa, numeri complessi...) penso si possa assumere conterrà
0 e 1 :)

Credo che il thread sia partito facendosi domande sul punto 2). False == 0
deriva dal fatto che per Python si sia scelto di avere aritmetica mista (il
fatto che bool subclassi int è un dettaglio di come si sia ottenuta). È una
scelta che si sarebbe potuto non fare, sono abbastanza sicuro che linguaggi
BDSM tipo Pascal non l'adottino, ma rientra abbastanza nello "stile
Python": è utile e, una volta deciso quanto fa int(B), non è ambigua (come
invece lo è int + str: in tanti linguaggi 10 + "20" ha un risultato e se
sia 30 o "1020" sta al gusto del suo progettista).

-- 
Daniele Varrazzo - Develer S.r.l. 
http://www.develer.com


Maggiori informazioni sulla lista Python