Perché la presenza di valore è valutata come "Truthy" in Python? [E.I. I tipi valutano True in condizionali]

0

Esempio:

if float: print('float is true?')

restituisce:

PerchétuttiglioggettidiversidaquelliesplicitamentedefiniticomeFalseo"False" valutano in modo veritiero?

    
posta ruben_KAI 03.09.2015 - 22:00
fonte

2 risposte

2

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:

  • un modulo di predicato con un'espressione che restituisce un valore booleano interpretabile.
  • un modulo contenitore con una singola variabile per verificare che questo contenitore non sia vuoto.

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.

    
risposta data 04.09.2015 - 00:18
fonte
-1

Why do all objects other than ones explicitly defined as False or "False" evaluate truthfully?

Semplice spiegazione:

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 .

Spiegazione filosofica:

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.

Spiegazione dell'esca di fiamma:

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.

Fai la tua scelta; -)

    
risposta data 03.09.2015 - 23:00
fonte

Leggi altre domande sui tag