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

Daniele Varrazzo piro a develer.com
Ven 5 Feb 2010 14:58:26 CET


On Fri, 05 Feb 2010 14:41:00 +0100, Pietro Battiston <toobaz a email.it>
wrote:
> Il giorno ven, 05/02/2010 alle 13.25 +0100, Daniele Varrazzo ha scritto:
>> 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).
> 
> A me veniva spontaneo identificare il lavoro su campi finiti, e in
> particolare sugli interi modulo 2^n, ed in particolare sugli interi
> modulo 2, con un'estensione dell'algebra di boole: per questo immaginavo
> con "+" lo xor. Ma riconosco che può essere un viaggio mentale mio, e
> comunque non c'entra molto col nocciolo del discorso.
> 
>> 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ì).
> 
> e qui ci siamo
> 
>> 
>> 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.
> 
> ci siamo
> 
>> 
>> 3) Deciso che deve fare un numero,
> 
> nel senso - e solo nel senso - che deve _comportarsi come un numero_ dal
> punto di vista del duck typing
> 
>> 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 :)
> 
> ci siamo
> 
>> 
>> Credo che il thread sia partito facendosi domande sul punto 2).
> 
> Credo di no: nel punto 2) ti chiedi se la somma e il casting automatico
> a int dei booleani abbia senso, e io come te credo di sì.
> 
> Il punto è solo se Bool deve essere una subclass di int.

La domanda originale, come riportata anche nel titolo è: perchè "0 in
(False,)" fa True? Questa è una diretta conseguenza di tuple.__contains__,
che porta alla domanda "perché '0 == False' fa True?". Questo è perché si è
desiderata l'aritmetica mista. Alessandro fa un passo ulteriore e "incolpa"
questa proprietà al fatto che bool sublassi int. Ma il subclassing è solo
il modo (economico) in cui si è deciso di implementare la proprietà: si
sarebbe potuto avere aritmetica mista senza subclass, ed entrambe le
domande nel titolo del post sarebbero ancora... domandabili.


> Ripeto: in un mondo ideale, io asserterei "True + 1 == 2" _e_ "True !=
> 1" senza timore...

A me un pò di timore fa... Se le due proprietà di sopra fossero vere:

True + 1 == 2 => True + 1 - 1 == 2 - 1 => True == 1

Quindi non puoi avere anche True != 1, a meno di non rompere il
funzionamento degli interi.

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


Maggiori informazioni sulla lista Python