Esempio:
if float: print('float is true?')
restituisce:
PerchétuttiglioggettidiversidaquelliesplicitamentedefiniticomeFalseo"False" valutano in modo veritiero?
Il linguaggio Python è strongmente influenzato da C. E C è un linguaggio orribile che non ha nemmeno un tipo booleano fino a C99. Invece, ha numeri interi. Tutto ciò che assomiglia a un intero zero è falso, qualsiasi altra cosa è vera. Si scopre che questo è molto comodo.
Vuoi testare un puntatore nullo? A differenza di Java, non devi specificare if (thing != null) foo(thing);
- è sufficiente un if (thing) foo(thing);
.
Vuoi controllare se abbiamo raggiunto la fine di una stringa? Basta discuterne in modo condizionale:
char c;
while ((c = *str++)) do_something(c);
Vuoi controllare se un array contiene elementi? Prova solo la lunghezza:
int n;
...;
if (n) we_have_items();
Quindi concettualmente, un condizionale ha due forme:
Sebbene Python abbia effettivi tipi booleani anziché sovraccaricare interi, mantiene questo meccanismo molto popolare per le raccolte. Ad esempio, None
(equivalente null
di Python), stringhe vuote ""
, elenchi vuoti []
e vuoti dicts {}
tutti valutano a False
in un contesto booleano. Questo di solito fa quello che vuoi, e se così non fosse, puoi essere esplicito riguardo alle tue esigenze. Ad esempio, puoi testare specificamente che una variabile non è None
:
if x is not None:
do_something_with(x)
Tuttavia, se sai che name
è una stringa facoltativa, quindi scrivi
if name:
print("hello, ", name)
else:
print("name required!")
è molto più comodo di
if bool(name): # manually force to-bool conversion
...
o
if name is not None and len(name): # explicitly state your intent: at least one character
...
o
if name is not None and bool(len(name)): # what the above example really means
...
o
if name is not None and len(xs) > 0: # even more explicit
...
È importante notare che queste conversioni implicite non sono magia nera che allontana il comodo tappeto del tipo di sicurezza da sotto i piedi. In Python, queste conversioni avvengono sempre in modo esplicito, ma se si passa una funzione o un valore incorporato, è possibile eseguire tali conversioni su quell'argomento. Ad esempio, puoi richiedere esplicitamente una conversione bool tramite bool(some_value)
. Quindi, se lo desideri, puoi pensare a if EXPRESSION: ...
incorporato come implementato come:
def if(EXPRESSION, then, else):
real_if bool(EXPRESSION):
then()
real_else:
else()
Puoi anche definire la tua conversione da-bool per le tue classi, implementando il metodo speciale __bool__(self)
. Ma attento! Le conversioni e l'overloading dell'operatore possono generare confusione per un utente a meno che la semantica non sia ovvia e intuitiva. In Python, è considerato sufficientemente chiaro per una conversione to-bool per verificare se una raccolta o un contenitore è vuoto. Per i non contenitori, potrebbe essere una buona idea usare invece un metodo ordinario, denominato.
Quindi perché ha senso che i valori valutino a True
anche quando non è stata definita alcuna conversione da-bool? I tipi definiti dall'utente hanno in genere una semantica di riferimento, vale a dire che la variabile contiene un puntatore al valore, non il valore stesso. Come abbiamo visto, l'idioma if (pointer) ...
C verifica se un puntatore non è vuoto, quindi ha senso estenderlo anche a Python che non ha puntatori reificati. Quindi il condizionale qui non verifica se il valore è vero o falso, ma se la variabile al momento detiene un valore. Se il tipo avesse una semantica del valore, troverei altamente confusa tale conversione to-bool, ma potrebbe essere solo il programmatore C ++ in me che parla.
Why do all objects other than ones explicitly defined as False or "False" evaluate truthfully?
Perché lo fanno, per definizione . Scusate se sembra una tautologia, ma questa è la risposta corretta: questo è il modo arbitrario in cui funziona perché questo è il modo arbitrario in cui è specificato che funzioni nelle regole arbitrarie, canoniche della lingua .
Dai un'occhiata a lo Zen di Python, che afferma:
Special cases aren't special enough to break the rules.
Se le regole sono che "questo specifico insieme di valori è falso e tutto il resto è verità", anche se sembra assurdo che un riferimento a un tipo sia o falso o falso, è un caso speciale, e non è abbastanza speciale da infrangere le regole.
Perché Python manca di un sistema di tipo statico appropriato, in cui gli unici valori True
e False
sarebbero True
e False
, e qualsiasi altra cosa verrebbe rifiutata al momento della compilazione. E poiché non puoi farlo in un linguaggio dinamico, Python prende la via più semplice invece di dedicare uno sforzo extra per farlo "nel modo giusto" (e buona fortuna a definirlo in questo contesto!) Anche quando significa accettare ovviamente- codice non valido e non sensato.
Leggi altre domande sui tag conditions python