3. Nozioni di base
![]() |
3.1. Un esempio di programma Python
Di seguito è riportato un programma che illustra le prime caratteristiche di Python.
# -*- coding=utf-8 -*-
# ----------------------------------
def affiche(chaine):
# visualizza stringa
print "chaine=%s" % (chaine)
# ----------------------------------
def afficheType(variable):
# visualizza il tipo di variabile
print "type[%s]=%s" % (variable,type(variable))
# ----------------------------------
def f1(param):
# aggiunge 10 a param
return param+10
# ----------------------------------
def f2():
# restituisce 3 valori
return ("un",0,100);
# -------------------------------- programma principale ------------------------------------
# questo è un commento
# variabile utilizzata senza essere stata dichiarata
nom="dupont"
# un messaggio sullo schermo
print "nom=%s" % (nom)
# un elenco con elementi di tipo diverso
liste=["un","deux",3,4]
# il numero dei suoi elementi
n=len(liste)
# un ciclo
for i in range(n):
print "liste[%d]=%s" % (i,liste[i])
# inizializzazione di 2 variabili con una tupla
(chaine1,chaine2)=("chaine1","chaine2")
# concatenazione delle 2 stringhe
chaine3=chaine1+chaine2
# visualizzazione del risultato
print "[%s,%s,%s]" % (chaine1,chaine2,chaine3)
# utilizzo di una funzione
affiche(chaine1)
# il tipo di una variabile può essere noto
afficheType(n)
afficheType(chaine1)
afficheType(liste)
# il tipo di una variabile può cambiare durante l'esecuzione
n="a change"
afficheType(n)
# una funzione può restituire un risultato
res1=f1(4)
print "res1=%s" % (res1)
# una funzione può restituire un elenco di valori
(res1,res2,res3)=f2()
print "(res1,res2,res3)=[%s,%s,%s]" % (res1,res2,res3)
# si sarebbero potuti recuperare questi valori in una variabile
liste=f2()
for i in range(len(liste)):
print "liste[%s]=%s" % (i, liste[i])
# test
for i in range(len(liste)):
# visualizza solo le stringhe
if (type(liste[i])=="str"):
print "liste[%s]=%s" % (i,liste[i])
# altri test
for i in range(len(liste)):
# visualizza solo i numeri interi >10
if (type(liste[i])=="int" and liste[i]>10):
print "liste[%s]=%s" % (i,liste[i])
# un ciclo while
liste=(8,5,0,-2,3,4)
i=0
somme=0
while(i<len(liste) and liste[i]>0):
print "liste[%s]=%s" % (i,liste[i])
somme+=liste[i] #somma=somma+t[i]
i+=1 #i=i+1
print "somme=%s" % (somme)
# fine programma
Nota:
- riga 1: un commento speciale che serve a dichiarare il tipo di codifica dello script, in questo caso UTF-8. Ciò dipende dall'editor di testo utilizzato. In questo caso con Notepad++:
![]() |
- riga 4: la parola chiave def definisce una funzione;
- righe 5-6: il contenuto della funzione. È indentato a destra di una tabulazione. È proprio questa indentazione, associata al carattere : dell’istruzione def, a definire il contenuto della funzione. Ciò vale per tutte le istruzioni che contengono un corpo: if, else, while, for, try, except;
- riga 12: Python gestisce internamente il tipo delle variabili. È possibile conoscere il tipo di una variabile con la funzione type(variable), che restituisce una variabile di tipo 'type'. L'espressione '%s' % (type(variable)) è una stringa di caratteri che rappresenta il tipo della variabile;
- riga 25: il programma principale. Questo viene dopo la definizione di tutte le funzioni dello script. Il suo contenuto non è indentato;
- riga 28: in Python non si dichiarano le variabili. Python distingue tra maiuscole e minuscole. La variabile Nom è diversa dalla variabile nom. Una stringa di caratteri può essere racchiusa tra virgolette " o apostrofi '. È quindi possibile scrivere 'dupont' o "dupont";
- riga 31: l'espressione "xxxx%syyyy%szzzz" % (100, 200) è la stringa "xxxx100yyy200szzzz" in cui ogni %s è stato sostituito da un elemento della tupla. %s è il formato di visualizzazione delle stringhe. Esistono altri formati;
- riga 34: c'è una differenza tra una tupla (1,2,3) (notare le parentesi) e una lista [1,2,3] (notare le parentesi quadre). La tupla è immutabile, mentre la lista è modificabile. In entrambi i casi, l’elemento n. i è indicato come [i];
- riga 40: range(n) è la tupla (0,1,2,...,n-1);
- riga 74: len(var) è il numero di elementi della collezione var (tupla, lista, dizionario, ...);
- riga 86: gli altri operatori booleani sono or e not.
I risultati visualizzati sullo schermo sono i seguenti:
3.2. Cambiamenti di tipo
Qui ci interessano le conversioni di tipo con dati di tipo str (stringa di caratteri), int (intero), float (reale), bool (booleano).
# -*- coding=utf-8 -*-
# conversioni di tipo
# int --> str, float, bool
x=4
print x, type(x)
x=str(4)
print x, type(x)
x=float(4)
print x, type(x)
x=bool(4)
print x, type(x)
# bool → int, float, str
x=True
print x, type(x)
x=int(True)
print x, type(x)
x=float(True)
print x, type(x)
x=str(True)
print x, type(x)
# str --> int, float, bool
x="4"
print x, type(x)
x=int("4")
print x, type(x)
x=float("4")
print x, type(x)
x=bool("4")
print x, type(x)
# float → str, int, bool
x=4.32
print x, type(x)
x=str(4.32)
print x, type(x)
x=int(4.32)
print x, type(x)
x=bool(4.32)
print x, type(x)
# gestione degli errori di conversione di tipo
try:
x=int("abc")
print x, type(x)
except ValueError, erreur:
print erreur
# casi vari del valore booleano
x=bool("abc")
print x, type(x)
x=bool("")
print x, type(x)
x=bool(0)
print x, type(x)
x=None
print x, type(x)
x=bool(None)
print x, type(x)
Sono possibili numerose conversioni di tipo. Alcune potrebbero fallire, come quella nelle righe 45-49 che tentano di convertire la stringa 'abc' in un numero intero. L'errore è stato gestito con una struttura try / except. Una forma generale di questa struttura è la seguente:
try:
actions
except Exception, Message:
actions
finally:
actions
Se una delle azioni del blocco try genera un'eccezione (segnala un errore), si passa immediatamente alla clausola except. Se le azioni del blocco try non generano eccezioni, la clausola except viene ignorata. Gli attributi Exception e Message dell'istruzione except sono facoltativi. Quando sono presenti, Exception specifica il tipo di eccezione intercettata dall’istruzione except, mentre Message contiene il messaggio di errore associato all’eccezione. Possono esserci più istruzioni except, se si desidera gestire diversi tipi di eccezione all’interno dello stesso try.
L'istruzione finally è facoltativa. Se presente, le azioni del finally vengono sempre eseguite, indipendentemente dal fatto che si sia verificata o meno un'eccezione.
Torneremo sulle eccezioni più avanti.
Le righe 52-61 mostrano vari tentativi di convertire un dato di tipo str, int, float, NoneType in un valore booleano. Ciò è sempre possibile. Le regole sono le seguenti:
- bool(int i) assume il valore False se i è pari a 0, True in tutti gli altri casi;
- bool(float f) è pari a False se f è pari a 0,0, True in tutti gli altri casi;
- bool(str stringa) è pari a False se stringa contiene 0 caratteri, True in tutti gli altri casi;
- bool(None) restituisce False. None è un valore speciale che indica che la variabile esiste ma non ha alcun valore.
I risultati visualizzati sullo schermo sono i seguenti:
3.3. L'ambito delle variabili
# -*- coding=utf-8 -*-
# ambito delle variabili
def f1():
# si utilizza la variabile globale i
global i
i+=1
j=10
print "f1[i,j]=[%s,%s]" % (i,j)
def f2():
# si utilizza la variabile globale i
global i
i+=1
j=20
print "f2[i,j]=[%s,%s]" % (i,j)
def f3():
# si utilizza una variabile locale i
i=1
j=30
print "f3[i,j]=[%s,%s]" % (i,j)
# test
i=0
j=0 # queste due variabili non sono note a una funzione f
# a meno che questa non le dichiari esplicitamente con l'istruzione global
# che intende utilizzarle
f1()
f2()
f3()
print "test[i,j]=[%s,%s]" % (i,j)
Risultati
Note:
- lo script mostra l'utilizzo della variabile i, dichiarata globale nelle funzioni f1 e f2. In questo caso, il programma principale e le funzioni f1 e f2 condividono la stessa variabile i.
3.4. Elenchi, tuple e dizionari
3.4.1. Liste unidimensionali
# -*- coding=utf-8 -*-
# liste unidimensionali
# inizializzazione
list1=[0,1,2,3,4,5]
# iterazione - 1
print "list1 a %s elements" % (len(list1))
for i in range(len(list1)):
print "list1[%s]=%s" % (i, list1[i])
list1[1]=10;
# scorrimento - 2
print "list1 a %s elements" % (len(list1))
for element in list1:
print element
# aggiunta di due elementi
list1[len(list1):]=[10,11]
print ("%s") % (list1)
# eliminazione degli ultimi due elementi
list1[len(list1)-2:]=[]
print ("%s") % (list1)
# aggiunta di una tupla all'inizio dell'elenco
list1[:0]=[-10, -11, -12]
print ("%s") % (list1)
# inserimento di due elementi a metà della lista
list1[3:3]=[100,101]
print ("%s") % (list1)
# eliminazione di due elementi a metà della lista
list1[3:4]=[]
print ("%s") % (list1)
Note:
- la notazione tabella[i:j] indica gli elementi da i a j-1 della tabella;
- la notazione [i:] indica gli elementi a partire da i della tabella;
- la notazione [:i] indica gli elementi da 0 a i-1 dell'array;
- riga 20: print (%s) % (list1) visualizza la stringa di caratteri: "[ list1[0], list1[2], ..., list1[n-1]]".
Risultati
Il codice precedente può essere scritto in modo diverso (bases_03b) utilizzando alcuni metodi delle liste:
# -*- coding=utf-8 -*-
# liste unidimensionali
# inizializzazione
list1=[0,1,2,3,4,5]
# scorrimento - 1
print "list1 a %s elements" % (len(list1))
for i in range(len(list1)):
print "list1[%s]=%s" % (i, list1[i])
list1[1]=10
# scorrimento - 2
print "list1 a %s elements" % (len(list1))
for element in list1:
print element
# aggiunta di due elementi
list1.extend([10,11])
print ("%s") % (list1)
# eliminazione degli ultimi due elementi
del list1[len(list1)-2:]
print ("%s") % (list1)
# aggiunta di una tupla all'inizio dell'elenco
for i in (-12, -11, -10):
list1.insert(0,i)
print ("%s") % (list1)
# inserimento a metà lista
for i in (101,100):
list1.insert(3,i)
print ("%s") % (list1)
# eliminazione a metà della lista
del list1[3:4]
print ("%s") % (list1)
I risultati ottenuti sono gli stessi della versione precedente.
3.4.2. Il dizionario
# -*- coding=utf-8 -*-
def existe(conjoints,mari):
# verifica se la chiave «mari» esiste nel dizionario «conjoints»
if(conjoints.has_key(mari)):
print "La cle [%s] existe associee a la valeur [%s]" % (mari, conjoints[mari])
else:
print "La cle [%s] n'existe pas" % (mari)
# ----------------------------- Main
# dizionari
conjoints={"Pierre":"Gisele", "Paul":"Virginie", "Jacques":"Lucette","Jean":""}
# percorso - 1
print "Nombre d'elements du dictionnaire : %s " % (len(conjoints))
for (cle,valeur) in conjoints.items():
print "conjoints[%s]=%s" % (cle,valeur)
# elenco delle chiavi del dizionario
print "liste des cles-------------"
cles=conjoints.keys()
print ("%s") % (cles)
# elenco dei valori del dizionario
print "liste des valeurs------------"
valeurs=conjoints.values()
print ("%s") % (valeurs)
# ricerca di una chiave
existe(conjoints,"Jacques")
existe(conjoints,"Lucette")
existe(conjoints,"Jean")
# eliminazione di una coppia chiave-valore
del (conjoints["Jean"])
print "Nombre d'elements du dictionnaire : %s " % (len(conjoints))
print ("%s") % (conjoints)
Note:
- riga 17: conjoints.items() restituisce l'elenco delle coppie (chiave, valore) del dizionario congiunte;
- riga 22: conjoints.keys() restituisce le chiavi del dizionario conjoints;
- riga 27: conjoints.values() restituisce i valori del dizionario «conjoints»;
- riga 7: conjoints.has_key(mari) restituisce True se la chiave mari esiste nel dizionario conjoints, False in caso contrario;
- riga 38: un dizionario può essere visualizzato su una sola riga.
3.4.3. Le tuple
# -*- coding=utf-8 -*-
# tupla
# inizializzazione
tab1=(0,1,2,3,4,5)
# iterazione - 1
print "tab1 a %s elements" % (len(tab1))
for i in range(len(tab1)):
print "tab1[%s]=%s" % (i, tab1[i])
# scorrimento - 2
print "tab1 a %s elements" % (len(tab1))
for element in tab1:
print element
# modifica di un elemento
tab1[0]=-1
Note:
- righe 15-18 dei risultati: dimostrano che una tupla non può essere modificata.
3.4.4. Le liste multidimensionali
# -*- coding=utf-8 -*-
# liste multidimensionali
# inizializzazione
multi=[[0,1,2], [10,11,12,13], [20,21,22,23,24]]
# percorso
for i1 in range(len(multi)):
for i2 in range(len(multi[i1])):
print "multi[%s][%s]=%s" % (i1,i2,multi[i1][i2])
# dizionari multidimensionali
# inizializzazione
multi={"zero":[0,1], "un":[10,11,12,13], "deux":[20,21,22,23,24]}
# scorrimento
for (cle,valeur) in multi.items():
for i2 in range(len(multi[cle])):
print "multi[%s][%s]=%s" % (cle,i2,multi[cle][i2])
3.4.5. Collegamenti tra stringhe ed elenchi
# -*- coding=Utf-8 -*-
# da stringa a lista
chaine='1:2:3:4'
tab=chaine.split(':')
print type(tab)
# visualizzazione lista
print "tab a %s elements" % (len(tab))
print ("%s") % (tab)
# da elenco a stringa
chaine2=":".join(tab)
print "chaine2=%s" % (chaine2)
# aggiungiamo un campo vuoto
chaine+=":"
print "chaine=%s" % (chaine)
tab=chaine.split(":")
# visualizzazione elenco
print "tab a %s elements" % (len(tab))
print ("%s") % (tab)
# aggiungiamo di nuovo un campo vuoto
chaine+=":"
print "chaine=%s" % (chaine)
tab=chaine.split(":")
# visualizzazione elenco
print "tab a %s elements" % (len(tab))
print ("%s") % (tab)
Note:
- riga 5: il metodo chaine.split(separatore) suddivide la stringa di caratteri chaine in elementi separati da séparateur e li restituisce sotto forma di lista. Pertanto, l'espressione '1:2:3:4'.split(":") ha come valore l'elenco ('1','2','3','4');
- riga 13: 'separateur'.join(liste) ha come valore la stringa 'lista[0]+separatore+lista[1]+separatore+...'.
3.5. Espressioni regolari
# -*- coding=utf-8 -*-
import re
# --------------------------------------------------------------------------
def compare(modele,chaine):
# confronta la stringa stringa con il modello modello
# visualizzazione dei risultati
print "\nResultats(%s,%s)" % (chaine,modele)
match=re.match(modele,chaine)
if match:
print match.groups()
else:
print "La chaine [%s] ne correspond pas au modele [%s]" % (chaine,modele)
# espressioni regolari in Python
# recupera i diversi campi di una stringa
# il modello: una sequenza di cifre racchiusa tra caratteri qualsiasi
# si desidera estrarre solo la sequenza di cifre
modele=r"^.*?(\d+).*?$"
# si confronta la stringa con il modello
compare(modele,"xyz1234abcd")
compare(modele,"12 34")
compare(modele,"abcd")
# il modello: una sequenza di cifre circondata da caratteri qualsiasi
# si desidera la sequenza di cifre insieme ai campi che la precedono e la seguono
modele=r"^(.*?)(\d+)(.*?)$"
# si confronta la stringa con il modello
compare(modele,"xyz1234abcd")
compare(modele,"12 34")
compare(modele,"abcd")
# il modello: una data nel formato gg/mm/aa
modele=r"^\s*(\d\d)\/(\d\d)\/(\d\d)\s*$"
compare(modele,"10/05/97")
compare(modele," 04/04/01 ")
compare(modele,"5/1/01")
# il modello: un numero decimale
modele=r"^\s*([+|-]?)\s*(\d+\.\d*|\.\d+|\d+)\s*$"
compare(modele,"187.8")
compare(modele,"-0.6")
compare(modele,"4")
compare(modele,".6")
compare(modele,"4.")
compare(modele," + 4")
# fine
Note:
- si noti il modulo importato alla riga 3. È proprio questo che contiene le funzioni per la gestione delle espressioni regolari;
- riga 10: il confronto tra una stringa e un'espressione regolare (modello) restituisce il valore booleano True se la stringa corrisponde al modello, False in caso contrario;
- riga 12: match.groups() è una tupla i cui elementi sono le parti della stringa che corrispondono agli elementi dell'espressione regolare racchiusi tra parentesi. Nel modello:
- ^.*?(\d+).*?, match.groups() sarà una tupla a un elemento;
- ^(.*?)(\d+)(.*?)$, match.groups() sarà una tupla di 3 elementi.
3.6. Modalità di passaggio dei parametri delle funzioni
# -*- coding=utf-8 -*-
def f1(a):
a=2
def f2(a,b):
a=2
b=3
return (a,b)
# ------------------------ main
x=1
f1(x)
print "x=%s" % (x)
(x,y)=(-1,-1)
(x,y)=f2(x,y)
print "x=%s, y=%s" % (x,y)
Note:
- in Python tutto è un oggetto. Alcuni oggetti sono detti «immutabili»: non è possibile modificarli. È il caso dei numeri, delle stringhe di caratteri e delle tuple. Quando gli oggetti Python vengono passati come parametri alle funzioni, vengono passati i loro riferimenti, a meno che tali oggetti non siano «immutabili», nel qual caso viene passato il valore dell’oggetto;
- le funzioni f1 (riga 3) e f2 (riga 6) intendono illustrare il passaggio di un parametro di uscita. Si vuole che il parametro effettivo di una funzione venga modificato dalla funzione stessa;
- righe 3-4: la funzione f1 modifica il proprio parametro formale a. Si vuole verificare se anche il parametro effettivo verrà modificato.
- righe 12-13: il parametro effettivo è x=1. Il risultato della riga 1 mostra che il parametro effettivo non viene modificato. Pertanto, il parametro effettivo x e il parametro formale a sono due oggetti distinti;
- righe 6-9: la funzione f2 modifica i propri parametri formali a e b e li restituisce come risultati;
- righe 15-16: si passano a f2 i parametri effettivi (x,y) e il risultato di f2 viene assegnato a (x,y). La riga 2 dei risultati mostra che i parametri effettivi (x,y) sono stati modificati.
Se ne deduce che, quando oggetti "immutabili" fungono da parametri di uscita, questi devono far parte dei risultati restituiti dalla funzione.
3.7. I file di testo
# -*- coding=utf-8 -*-
import sys
# elaborazione sequenziale di un file di testo
# il file è costituito da una serie di righe della forma login:pwd:uid:gid:infos:dir:shell
# ogni riga viene inserita in un dizionario nella forma login => [uid,gid,infos,dir,shell]
# --------------------------------------------------------------------------
def afficheInfos(dico,cle):
# visualizza il valore associato alla chiave nel dizionario "dico", se esiste
valeur=None
if dico.has_key(cle):
valeur=dico[cle]
if 'list' in str(type(valeur)):
print "[{0},{1}]".format(cle,":".join(valeur))
else:
# la chiave non è presente nel dizionario «dico»
print "la cle [{0}] n'existe pas".format(cle)
def cutNewLineChar(ligne):
# si rimuove il carattere di fine riga dalla riga, se presente
l=len(ligne);
while(ligne[l-1]=="\n" or ligne[l-1]=="\r"):
l-=1
return(ligne[0:l]);
# si imposta il nome del file
INFOS="infos.txt"
# lo si apre in modalità di creazione
try:
fic=open(INFOS,"w")
except:
print "Erreur d'ouverture du fichier INFOS en écriture\n"
sys.exit()
# si genera un contenuto arbitrario
for i in range(1,101):
ligne="login%s:pwd%s:uid%s:gid%s:infos%s:dir%s:shell%s" % (i,i,i,i,i,i,i)
fic.write(ligne+"\n")
# si chiude il file
fic.close()
# si apre in lettura
try:
fic=open(INFOS,"r")
except:
print "Erreur d'ouverture du fichier INFOS en écriture\n"
sys.exit()
# dizionario inizialmente vuoto
dico={}
# lettura riga
ligne=fic.readline()
while(ligne!=''):
# si rimuove il carattere di fine riga
ligne=cutNewLineChar(ligne)
# si inserisce la riga in un array
infos=ligne.split(":")
# si recupera il login
login=infos[0]
# si rimuovono i primi due elementi [login,pwd]
infos[0:2]=[]
# si crea una voce nel dizionario
dico[login]=infos
# lettura riga
ligne=fic.readline()
# si chiude il file
fic.close()
# elaborazione del dizionario
afficheInfos(dico,"login10")
afficheInfos(dico,"X")
Note:
- riga 37: per terminare lo script a metà del codice.
Il file infos.txt:
login0:pwd0:uid0:gid0:infos0:dir0:shell0
login1:pwd1:uid1:gid1:infos1:dir1:shell1
login2:pwd2:uid2:gid2:infos2:dir2:shell2
...
login98:pwd98:uid98:gid98:infos98:dir98:shell98
login99:pwd99:uid99:gid99:infos99:dir99:shell99
Risultati sullo schermo:

