Abbiamo visto che alcune funzioni possono essere chiamate con un numero variabile di argomenti. In Python ci sono più modi per ottenere questo comportamento: qui vedremo quello più usato, cioè i parametri con valori di default.
Riprendete il programma "saluti.py" (qui) e modificatelo così:
def saluta(nome="Peppe"):
print ("Ciao", nome + "!")
saluta()
saluta("Ciccio")
n = input("Chi vuoi salutare? ")
saluta(n)
Nella definizione di saluta()
dopo il parametro nome
abbiamo aggiunto ="Peppe"
.
Questo vuol dire che quel parametro ha un valore di default: se l'utente chiama la
funzione senza argomenti, Python sostituisce automaticamente "Peppe"
al posto del parametro
nome
, se invece l'utente specifica un argomento, la sostituzione avviene normalmente.
Nella definizione di una funzione possiamo avere sia parametri con valore di default (opzionali) sia parametri ordinari (obbligatori). Gli argomenti opzionali devono sempre seguire quelli obbligatori nella lista dei parametri.
Vediamo qualche esempio:
def funz1(a, b, c=0, d=1): # OK, 2 paranetri ordinari e 2 di default
...
def funz2(a=1, b=2, c=3): # OK, 3 parametri di default
...
def funz3(a=1, b): # Errore: il parametro di default precede quello ordinario
...
Avrete notato che non ho lasciato spazi prima e dopo il segno di =
nella definizione dei
valori di default: anche questo non è obbligatorio (si possono lasciare quanti spazi si vuole sia prima che dopo),
ma è diventata un'abitudine comune, probabilmente per distinguere i valori di default dalle assegnazioni;
conviene quindi adottare questa convenzione. Vediamo un altro esempio:
def compra(cosa, prezzo, quantita=1):
print("Mi serve", quantita, "etto di", cosa)
print("Ecco qui")
print("Quanto costa?")
print(prezzo * quantita, "euro")
compra("Prosciutto", 1.5, 2) # compra 2 etti di prosciutto a 1.5 euro l'uno
compra("Salame", 1.0) # compra 1 etto (default) di salame a 1.0 euro
compra("Carne") # ERRORE! un solo argomento (ne servono almeno 2)
nella prima chiamata abbiamo scritto tutti e tre i parametri della funzione, nella seconda abiamo
omesso il parametro opzionale quantita
(e Python ha sostituito 1 al posto di esso) mentre nel terzo abbiamo
causato un errore omettendo due parametri (uno solo è opzionale).
Non c'è limite al numero di argomenti (obbligatori od opzionali) che una funzione può avere. Quando però ci sono molti parametri di default le cose si complicano: tenete sempre presente che Python effettua le sostituzioni secondo l'ordine dei parametri nella definizione.
Copiate questo codice ed eseguitelo:
def analisi_logica(sogg, verbo, compl_ogg="", compl_luogo="", compl_tempo=""):
print(sogg, verbo, compl_ogg, compl_luogo, compl_tempo)
print("SOGGETTO: ", sogg)
print("PREDICATO: ", verbo)
if len(compl_ogg) > 0:
print("COMPLEMENTO OGGETTO:", compl_ogg)
if len(compl_luogo) > 0:
print("COMPLEMENTO DI LUOGO:", compl_luogo)
if len(compl_tempo) > 0:
print("COMPLEMENTO DI TEMPO:", compl_tempo)
analisi_logica("Io", "mangio")
analisi_logica("Gigi", "mangia", "un panino")
analisi_logica("Peppe", "sta mangiando", "la pastasciutta", "a tavola")
Dopo aver ben compreso cosa fa la funzione analisi_logica()
chiedetevi: cosa succederebbe
se io volessi fare l'analisi logica di "Io mangio a mezzogiorno"? Dovrei passare alla funzione i parametri
sogg, verbo, compl_tempo
(cioè i primi due, obbligatori, più il quinto, opzionale) ma come potrebbe
capire Python quale dei tre parametri opzionali gli sto passando?
Una soluzione potrebbe essere quella di chiamare la funzione in questo modo:
analisi_logica("Io", "mangio", "", "", "a mezzogiorno")
rispettando così l'ordine degli argomenti che abbiamo stabilito nella definizione della funzione. Questo ci costringe però ad indicare nella chiamata tutti i parametri, anche quelli opzionali, vanificando la possibilità di tralasciare quelli che non ci servono.
Il problema è risolto elegantemente da Python con la possibilità di inserire il nome degli argomenti che stiamo passando anche nella chiamata della funzione. Provate ad aggiungere in coda al programma queste altre due righe:
analisi_logica("Io", "mangio", compl_tempo="a mezzogiorno")
analisi_logica("Luigi", "mangia", compl_luogo="al ristorante")
In questo modo indichiamo esplicitamente a Python che deve sostituire la stringa "a mezzogiorno"
al posto del parametro formale compl_tempo
indicato nella definizione della funzione e la stringa
"al ristorante"
al posto del parametro compl_luogo
.
Quando indichiamo esplicitamente il nome di un parametro non siamo più vincolati all'ordine della definizione (e questo è senz'altro utile se i parametri sono molti e non ricordiamo più il loro ordine). Inoltre possiamo indicare con il nome anche i parametri obbligatori (che comunque non possono mai essere omessi). Python chiama i parametri senza il nome positional arguments (parametri che saranno sostituiti in base alla loro posizione) e quelli con il nome keyword arguments (parametri sostituiti in base al loro nome); L'unica restrizione è che, se usiamo keywords arguments nella chiamata, essi devono seguire i positional arguments. Provate queste altre chiamate:
analisi_logica(compl_ogg="un cornetto", sogg="Io", verbo="mangio")
analisi_logica(verbo="mangia", sogg="Luigino")
analisi_logica(compl_ogg="la pasta", "Mio cugino", "mangia")
L'ultima chiamata provoca un errore perchè un keyword argument viene prima dei positional arguments. Per finire
analizziamo meglio la vecchia e cara funzione print()
: solo adesso possiamo
capire cosa fa veramente.
>>> help(print)
Help on built-in function print in module builtins: print(...) print(value, ..., sep=' ', end='\n', file=sys.stdout, flush=False) Prints the values to a stream, or to sys.stdout by default. Optional keyword arguments: file: a file-like object (stream); defaults to the current sys.stdout. sep: string inserted between values, default a space. end: string appended after the last value, default a newline. flush: whether to forcibly flush the stream.
Analizzando i parametri di print()
, vediamo che value, ...,
rappresentano
la lista variabile di argomenti che deve stampare (non tratteremo qui come si fa). Più interessanti sono
i parametri di default. Leggendo la descrizione in inglese apprendiamo che:
Parametro | Significato |
---|---|
sep |
E'la stringa che viene inserita tra i vari valori da stampare: di default uno spazio |
end |
E' la stringa che viene stampata dopo l'ultimo argomento, di default un \n
(a capo) |
file |
E' un oggetto di tipo file (li vedremo nella prossima lezione) sul quale vengono stampati
gli argomenti: di default la console di IDLE (sys.stdout indica l'output standard
del sistema) |
flush |
Controlla la stampa nei file, non ce ne occupiamo qui |
Quindi usando i parametri sep
e end
, possiamo cambiare notevolmente il
comportamento standard di print()
. Possiamo ad esempio evitare che la funzione vada a
capo sostituendo il carattere "\n" del parametro end
con uno spazio od una stringa vuota.
>>> print("Amo", "la", "mia", "mamma", sep="_____")
>>> print("Ciao mamma", end="*******\n")
>>> print("Ciao mamma", end="\n\n\n")
ESERCIZIO 18.3 Data la funzione:
def mi_presento(nome="Peppe", eta=18, citta="Roma"):
print("Mi chiamo", nome, "ho", anni, "anni e abito a", citta)
Copiatela nel vostro programma e chiamatela tre volte con un numero di parametri differente
Fine della lezione