Python: usare identità e appartenenza per validare dati e filtrare input

by theArchitect
SHARE
Python: usare identità e appartenenza per validare dati e filtrare input
© Guida-HTML5.it

Introduzione

Quando si lavora con dati provenienti da utenti, file o API, è spesso necessario verificare se una variabile rappresenta un valore preciso oppure se appartiene a un insieme di valori consentiti. Python mette a disposizione due categorie di operatori molto utili per questo scopo:

  • operatori di identità, is e is not;
  • operatori di appartenenza, in e not in.

Questi operatori sembrano semplici, ma usarli correttamente evita errori frequenti, soprattutto quando si gestiscono valori mancanti, liste di opzioni valide, dizionari e stringhe. In questo tutorial costruiremo un piccolo validatore per un ordine online. Il programma controllerà lo stato dell’ordine, verificherà la presenza di campi obbligatori e applicherà regole basate su liste di valori consentiti.

È importante distinguere il confronto tra valori dal controllo dell’identità degli oggetti. L’operatore == verifica se due valori sono equivalenti; is verifica invece se due variabili fanno riferimento allo stesso oggetto in memoria. Per controllare valori come stringhe e numeri si usa normalmente ==, non is.

Codice completo

# Dati ricevuti da un possibile modulo di e-commerce
ordine = {
    "id": "ORD-1042",
    "cliente": "Giulia",
    "stato": "spedito",
    "metodo_pagamento": "carta",
    "note": None,
    "prodotti": ["tastiera", "mouse"]
}

# Valori ammessi dal dominio applicativo
stati_validi = {"nuovo", "in lavorazione", "spedito", "consegnato"}
metodi_pagamento_validi = {"carta", "paypal", "bonifico"}

# Controllo di identità: None è un valore speciale
if ordine["note"] is None:
    print("Nessuna nota aggiuntiva.")

# Controllo di appartenenza allo stato consentito
if ordine["stato"] in stati_validi:
    print(f"Stato valido: {ordine[´stato´]}")
else:
    print("Errore: stato dell´ordine non riconosciuto.")

# Verifica del metodo di pagamento
if ordine["metodo_pagamento"] not in metodi_pagamento_validi:
    print("Errore: metodo di pagamento non supportato.")
else:
    print("Metodo di pagamento accettato.")

# Verifica della presenza di un prodotto specifico
if "tastiera" in ordine["prodotti"]:
    print("La tastiera è presente nell´ordine.")

# Controllo dei campi obbligatori
campi_obbligatori = {"id", "cliente", "stato", "metodo_pagamento"}
campi_presenti = set(ordine)

campi_mancanti = campi_obbligatori - campi_presenti

if campi_mancanti:
    print(f"Campi mancanti: {´, ´.join(campi_mancanti)}")
else:
    print("Tutti i campi obbligatori sono presenti.")

# Esempio esplicito di identità tra oggetti
valore_mancante = None

if valore_mancante is None:
    print("Il valore è realmente assente.")

# Confronto di valore: usare == per confrontare contenuti
stato_atteso = "spedito"

if ordine["stato"] == stato_atteso:
    print("L´ordine ha lo stato atteso.")

Spiegazione

Controllare i valori mancanti con is None

None rappresenta l’assenza intenzionale di un valore. Per verificare se una variabile contiene proprio None, la forma consigliata è:

if valore is None:
    print("Valore assente")

Non è buona pratica sostituire questa verifica con confronti poco chiari o con controlli basati sulla conversione a stringa. None non significa necessariamente stringa vuota, zero o valore falso: è un oggetto speciale che indica una situazione distinta.

Usare in con liste, set e dizionari

L’operatore in controlla se un elemento appartiene a una collezione. Con una lista verifica la presenza di un elemento; con un set svolge lo stesso compito in modo generalmente più efficiente; con un dizionario controlla invece le chiavi.

colori = ["rosso", "verde", "blu"]

if "verde" in colori:
    print("Colore disponibile")

configurazione = {
    "debug": True,
    "lingua": "it"
}

if "lingua" in configurazione:
    print("La lingua è configurata")

Nel caso dell’ordine, l’espressione ordine["stato"] in stati_validi consente di accettare soltanto stati definiti dal dominio dell’applicazione. Un set è particolarmente adatto quando l’obiettivo principale è controllare l’appartenenza e non mantenere l’ordine degli elementi.

Usare not in per bloccare valori non validi

not in è utile per esprimere direttamente una condizione negativa:

ruoli_autorizzati = {"admin", "editor"}

ruolo = "visitatore"

if ruolo not in ruoli_autorizzati:
    print("Accesso negato")

Questo approccio rende il codice leggibile e riduce la necessità di catene di condizioni come if ruolo != "admin" and ruolo != "editor".

La differenza tra is e ==

Consideriamo due stringhe con lo stesso contenuto:

primo = "spedito"
secondo = "".join(["spe", "dito"])

print(primo == secondo)  # True: stesso contenuto
print(primo is secondo)  # Non va usato per confrontare stringhe

Il risultato di is può dipendere da dettagli interni dell’interprete, come il riutilizzo di alcuni oggetti. Per questo motivo is va riservato soprattutto a valori singleton come None, mentre == va usato per confrontare i contenuti.

Best practice

  • Usa is None e is not None per controllare l’assenza di un valore.
  • Usa == per confrontare stringhe, numeri e altri valori, non is.
  • Preferisci un set quando devi eseguire molti controlli di appartenenza e l’ordine non è importante.
  • Centralizza i valori ammessi in costanti o collezioni dedicate, invece di ripeterli in più condizioni.
  • Verifica le chiavi prima di accedere ai dizionari se i dati possono essere incompleti:
if "email" not in utente:
    print("Email obbligatoria")
else:
    print(utente["email"])
  • Non confondere una collezione vuota con un valore mancante: una lista vuota può significare “nessun elemento”, mentre None può significare “informazione non disponibile”.
  • Scrivi condizioni leggibili. Una condizione leggermente più lunga ma chiara è preferibile a un’espressione compatta e difficile da interpretare.

Riepilogo

Gli operatori di identità e appartenenza sono strumenti fondamentali per validare dati e costruire condizioni affidabili. is e is not servono principalmente a riconoscere oggetti speciali, in particolare None. in e not in permettono invece di verificare rapidamente se un elemento, una chiave o un valore appartiene a una collezione.

La distinzione più importante da ricordare è questa: usa == per confrontare il contenuto di due valori e is per controllare l’identità di un oggetto. Applicando questa regola, insieme a set e dizionari usati con criterio, puoi scrivere validatori più chiari, sicuri e facili da mantenere.

Approfondisci con risorse ufficiali

SHARE