Raccolta Snippet Python #1

10 snippet pronti e commentati: fondamenti “usati male” + casi tipici che creano bug.

1) Argomenti di default mutabili (il classico bug)

Liste/dizionari come default vengono “riusati” tra chiamate. Soluzione: None + inizializzazione interna.

def aggiungi(valore, lista=None):
    # MAI usare lista=[] come default: viene condivisa tra chiamate
    if lista is None:
        lista = []          # nuova lista ogni volta
    lista.append(valore)
    return lista

print(aggiungi(1))          # [1]
print(aggiungi(2))          # [2] (non [1,2])
bug comunefunzioni

2) == vs is (uguaglianza vs identità)

== confronta il valore. is confronta se è lo stesso oggetto. Usare is soprattutto con None.

a = [1, 2]
b = [1, 2]

print(a == b)   # True  (stesso contenuto)
print(a is b)   # False (oggetti diversi)

x = None
if x is None:
    print("x non è impostato")
fondamentibest practice

3) for / else (non è “if/else”, è “loop completato”)

Il blocco else parte solo se il ciclo termina senza break. Utilissimo per ricerche.

numeri = [3, 7, 11, 15]
target = 8

for n in numeri:
    if n == target:
        print("Trovato!")
        break
else:
    # Arriva qui SOLO se non ha mai fatto break
    print("Non trovato")
patternleggibilità

4) try / except / else / finally (struttura corretta)

else si esegue solo se non ci sono eccezioni. finally sempre (pulizia risorse).

def dividi(a, b):
    try:
        risultato = a / b
    except ZeroDivisionError:
        return "Errore: divisione per zero"
    else:
        # qui arrivo SOLO se non ci sono eccezioni
        return risultato
    finally:
        # qui ci arrivo SEMPRE
        pass

print(dividi(10, 2))
print(dividi(10, 0))
error handlingrobustezza

5) Copia: assegnazione, shallow copy, deep copy

Bug frequente: copiare una lista di liste senza deep copy. Qui vedi subito la differenza.

import copy

a = [[1, 2], [3, 4]]

b = a            # stessa reference (NON copia)
c = a.copy()     # shallow copy (copio solo il contenitore)
d = copy.deepcopy(a)  # deep copy (copio anche le liste interne)

a[0].append(99)

print("a:", a)
print("b:", b)   # cambia anche b
print("c:", c)   # cambia anche c (shallow!)
print("d:", d)   # resta indipendente
listebug comune

6) *args e **kwargs (passaggio flessibile parametri)

Utile per wrapper, logging, funzioni “ponte”. Qui vedi come si raccolgono e come si “espandono”.

def logga(*args, **kwargs):
    print("args:", args)       # tupla
    print("kwargs:", kwargs)   # dizionario

logga(1, "ciao", debug=True, timeout=2)

def somma(a, b):
    return a + b

valori = (3, 4)
print(somma(*valori))          # espansione tuple -> a=3,b=4
funzionisintassi

7) Unpacking (scambio valori, “rest”, e ignorare con _)

Semplifica tantissimo il codice. Occhio a usare *rest per catturare il resto.

a, b = 10, 20
a, b = b, a   # swap senza variabile temporanea
print(a, b)

valori = [1, 2, 3, 4, 5]
primo, secondo, *resto = valori
print(primo, secondo, resto)

x, _, y = (100, 999, 200)  # ignoro il valore in mezzo
print(x, y)
pythonicoleggibilità

8) Comprehension vs loop (e quando NON usarla)

Le comprehension sono ottime, ma se diventa illeggibile… meglio un loop chiaro.

numeri = [1, 2, 3, 4, 5, 6]

# Comprehension: chiara e compatta
pari = [n for n in numeri if n % 2 == 0]
print(pari)

# Se serve logica complessa, meglio il loop
ris = []
for n in numeri:
    if n % 2 == 0:
        ris.append(n * 10)
print(ris)
stilebest practice

9) with per file: chiusura sicura e automatica

Evita file lasciati aperti, soprattutto in caso di errori. È la forma corretta.

# Scrivo
with open("demo.txt", "w", encoding="utf-8") as f:
    f.write("Ciao Pierduino!\n")

# Leggo
with open("demo.txt", "r", encoding="utf-8") as f:
    contenuto = f.read()

print(contenuto)
filefondamentali

10) if __name__ == "__main__" (script vs modulo)

Permette di eseguire test/demo solo quando il file è lanciato direttamente.

def main():
    print("Esecuzione principale")

# Questo blocco parte SOLO se esegui: python miofile.py
# Se invece importi il file, non parte automaticamente.
if __name__ == "__main__":
    main()
moduliorganizzazione
Copiato negli appunti