Avviso!
Questo articolo è basato su una versione obsoleta di python; può ancora essere utile come tutorial basilare, ma non copre le molte features introdotte nel corso degli ultimi anni.Perché un altro linguaggio?
Già mi sembra di sentirvi urlare disperati: "Noo! Perché un altro linguaggio?", peggio: "Perché un altro linguaggio interpretato?". Forse non avete tutti i torti ma, a parte semplicistiche considerazioni stile "meglio uno di più che uno di meno", vedrete che se concederete una possibilità a python1 (http://www.python.org) ve ne innamorerete facilmente.Ok, cosa sarebbe questo python?
Python è nato tra il 1989 e il 1990 ad opera di Guido Van Rossum che aveva già lavorato all'elegante linguaggio ABC, di scarsa fortuna. Python è un linguaggio interpretato (in verità pseudocompilato, ma non formalizziamoci 2) con alcune caratteristiche che lo rendono molto interessante; vediamone un elenco:- ad oggetti.
- piuttosto veloce.
- portabile 3.
- di altissimo livello, quindi con strutture dati complesse.
- estendibile in C, C++ e altri linguaggi.
- dotato di numerosi moduli sia standard sia scritti da terzi.
- sintassi molto chiara che lo rende facilmente leggibile.
- qualità delle interfacce dei moduli e della documentazione generalmente molto alta.
- utilizzabile sia per piccoli script che per progetti di notevoli dimensioni.
I vantaggi
In confronto ai linguaggi compilati i pregi di un interpretato sono evidenti: il tempo richiesto dal ciclo di sviluppo è inevitabilmente molto minore, il programma è facilmente modificabile ed inoltre è portabile su tutte le piattaforme per cui esiste l'interprete; per contro un interpretato paga queste qualità in termini di velocità di esecuzione, ma questo normalmente non rappresenta un grave problema per la maggior parte dei programmi.Nel campo degli interpretati la lotta è di certo più agguerrita e Python si scontra con i semplici script di shell come bash e tcsh che però risultano subito troppo lenti e poco potenti per progetti di una certa complessità e i due linguaggi di script di maggior successo: il Perl e il Tcl; tra questi il Python è di certo quello meno diffuso, ma di sicuro in questi ultimi anni si sta guadagnando molta popolarità, e sul piano della programmazione non ha nulla da invidiare ai diretti concorrenti essendo stato creato proprio cercando di prendere il meglio dai vari linguaggi disponibili.
Let's start with code!
A questo punto, sperando di non spaventarvi troppo, presento subito il codice di un piccolo script che tutto sommato fa cose non poi così piccole (fatelo in C con tutti i controlli del caso e fatemi sapere quante righe sono): le righe qui sotto si collegano al server POP-3 mail.ginopino.it (che spero non esista!) e controlla ogni 10 minuti se c'è posta per noi, nel qual caso stampa a video il numero di messaggi e la loro dimensione totale.Dottore! Questo codice sta male!
E allora smontiamolo pezzo per pezzo e analizziamolo...linea 1 | #!/usr/bin/python linea 2 | # questo è un commento inutile :-)Come ogni script anche i programmi python devono iniziare con il classico #! sulla prima riga seguito dal percorso dell'interprete. In Windows questa riga è ignorata, ed è importante che il file abbia estensione .py e che questa sia associata all'interprete. Il codice python può contenere commenti che andranno fatti precedere da #.
Come noterete da questo esempio i vari blocchi di codice in python non sono delimitati, come in molti altri linguaggi, da parentesi di qualche sorta o delimitatori di begin/end; l'interprete determina l'inizio e la fine dei vari blocchi usando l'indentazione (il numero di spazi o tab dall'inizio della riga): una volta aperto un nuovo blocco di codice (ad esempio per la dichiarazione di una funzione, per l'inizio di un ciclo o di una condizione if) la riga successiva dovrà essere indentata in modo più profondo della precedente e, una volta giunti alla fine del blocco di istruzioni (fine della definizione, del ciclo, dell'if...), si dovrà tornare ad allineare il codice allo stesso livello delle istruzioni precedenti. In questo modo il codice python risulta molto compatto e leggibile (in pratica costringe il programmatore a seguire un buono stile di scrittura); un buon consiglio può essere quello di usare sempre quattro spazi come tabulazione: il programma ne guadagnerà decisamente in estetica; la maggior parte degli editor di testo dovrebbero essere in grado di farvi settare il tab e di sostituirlo automaticamente con il corrispondente numero di spazi.
linea 3 | import poplib, sys, timeL'istruzione import importa i moduli specificati; in questo caso i moduli standard poplib per la gestione di caselle di posta POP-3, sys che contiene molte variabili ed alcune funzioni che interagiscono con l'interprete e con il sistema e time che gestisce funzioni e variabili riferite alla gestione del tempo e della data.
Un modulo è un file contenente definizioni
e altre istruzioni python; il file che contiene il modulo
deve avere estensione .py e viene importato
chiamandolo con nome del file privo di estensione. Ogni
modulo ha la sua tabella di simboli privata, questo
significa che ogni funzione ed ogni variabile definita in
un modulo non è direttamente visibile nel programma
che lo include, ma per riferirsi agli oggetti che contiene
sarà necessario usare una sintassi del tipo:
nomemodulo.nomeoggetto
import accetta anche un paio di varianti della sua
sintassi; la prima è:
from nomemodulo import oggetto1 oggetto2che importa solo gli oggetti oggetto1 e oggetto2 dal modulo nomemodulo; mentre la seconda:
from nomemodulo import *importa tutti gli oggetti da nomemodulo; in entrambi i casi gli oggetti importati saranno direttamente disponibili nello script (ad esempio sarà possibile riferirsi direttamente a oggetto1). Ovviamente queste ultime due sintassi possono essere utilizzate solo se non si andranno a creare conflitti con i nomi di variabili, classi, funzioni o altro specificato nel codice che va ad importare gli oggetti da moduli esterni; di norma la documentazione di un modulo indica se è o meno possibile procedere in questo modo.
Vi starete chiedendo come python trova i file che corrispondono ai moduli; è piuttosto semplice: prima di tutto cerca nella directory corrente un file di nome nomemodulo.py, se non è presente cerca il file nelle directory specificate nella variabile d'ambiente $PYTHONPATH, se questa non è settata o il modulo non è stato ancora trovato la ricerca continua in alcune directory di default dipendenti dal sistema operativo usato (in unix ".:/usr/local/lib/python"); se ancora il modulo non è stato trovato, verrà generata una eccezione di tipo ImportError (delle eccezioni ci occuperemo tra breve, non preoccupatevi). Alcuni dei moduli che abbiamo importati sono built-in nell'interprete python (e quindi sempre disponibili), mentre altri sono distribuiti in normali file (provate a cercare nella directory /usr/lib/python1.5), ma all'atto pratico questi due tipi di moduli sono assolutamente equivalenti.
Python dispone di un numero piuttosto elevato di moduli standard con un numero impressionante di funzioni già pronte: grazie a questi i vostri programmi potranno compiere azioni piuttosto complesse in poche righe. Documentazione estesa sui moduli standard può essere trovata sulla "Python Library Reference" che consiglio di tenere sempre a portata di mano.
linea 4 | def controlla_posta(): linea 5 | """Funzione che controlla una casella di posta"""Qui definiamo la funzione controlla_posta() che non riceve alcun argomento e restituirà due interi.
L'istruzione def consente di definire una nuova
funzione. La stringa sotto, racchiusa tra due coppie di tre
doppiapici è la docstring che descrive
brevemente lo scopo della funzione; deve essere di una riga
sola ma può essere seguita da uno spazio vuoto e da
una nuova docstring anche su più righe per
descrizioni più dettagliate; le docstring sono usate
per creare documentazione in automatico, quindi è
buona abitudine usarle (eventualmente tornerò
sull'uso delle docstring in un ipotetico capitolo sullo
stile di scrittura).
Una volta che la funzione verrà eseguita ci
troveremo in un nuovo spazio di simboli, quindi tutte le
variabili e gli oggetti che verranno qui definiti non
saranno direttamente visibili dal codice che ha chiamato la
funzione stessa.
Alle funzioni è possibile passare argomenti,
semplicemente elencandoli tra le parentesi separandoli con
virgole; è anche possibile assegnare valori di
default ad uno o più argomenti, ad esempio:
def prova(primo, secondo=3, terzo='Ciao'): print terzo, secondo * primoche potrà essere chiamata, indifferentemente con:
prova(2) prova(2, 4) prova(3, 5, 'Test')Invocazioni che avranno come rispettivo output:
Ciao 6 Ciao 8 Test 15Inutile sottolineare che chiamare la funzione con:
prova()si genererà un errore essendo presente nella dichiarazione della funzione almeno un argomento a cui non è stato assegnato un valore di default. L'errore sarà una eccezione TypeError che indicherà la riga in cui è avvenuto l'errore e una sua breve descrizione:
Traceback (innermost last): File "./test", line 6, in ? prova() TypeError: not enough arguments; expected 1, got 0È anche possibile definire una funzione che raccolga un numero variabile di argomenti:
def prova2(primo, secondo, *altri)Dove tutti gli argomenti oltre il secondo verranno assegnati ad una tuple (un tipo di dati consistente in un numero variabile di oggetti qualsiasi, una specie di lista; sui vari tipi di dati torneremo nel prossimo articolo).
Altra possibilità interessante è l'uso di argomenti keyword: in pratica è possibile invocare normalmente la funzione, ma nei valori di chiamata si passeranno delle coppie keyword: valore. Facciamo un esempio:
def funzione(primo, key1='gatto', key2='cane')Si potrà chiamare questa funzione indistintamente con:
funzione(42) funzione(0, key2='mucca') funzione(3, key1='balena', key2='scimmia')Mentre saranno errare le chiamate:
funzione() # almeno un argomento (primo) funzione(key3='branzino') # keyword non nota funzione(primo=0, 'verme') # variabile non keyword dopo una keyword funzione(primo=0, 4) # doppio valore assegnato ad una variabile
Da ricordare che in tutti i casi i valori di default passati ad una funzione sono valutati prima che entri in esecuzione la funzione stessa, sono quindi consentite perversioni del tipo:
variabile = 42 def funzione(primo, secondo=variabile, terzo=1):
Ma continuiamo ad analizzare il codice:
linea 6 | try: . . . linea 13 | except (poplib.socket.error, poplib.error_proto), messaggio:Creiamo una zona sottoposta al controllo delle eccezioni poplib.socket.error e poplib.error_proto.
Eccezioni ed errori di sintassi sono il
modo che python ha di farci capire che qualcosa è
andato storto: gli errori di sintassi si hanno quando il
parser non riesce ad interpretare quello che abbiamo
scritto: può essere dovuto ad una parentesi non
chiusa o ad una virgola al posto sbagliato; in questo caso
l'interprete interrompe la lettura del codice ed esce
stampando a video il punto in cui è stato incontrato
il problema. Le eccezioni invece vengono lanciate quando
una istruzione corretta ha incontrato un problema (per
esempio una divisione per zero, ma la casistica è
molto più ampia). Le eccezioni possono essere
catturate includendo la parte di codice che si pensa possa
generarle nella coppia di istruzioni try:
except:
Se una eccezione non viene catturata provocherà
l'interruzione del programma e conseguente stampa di un
messaggio di errore. In breve funziona così:
- Il parser identifica ed esegue il codice tra try ed except.
- Se nessuna eccezione viene lanciata, il codice dopo except non viene eseguito.
- Se una eccezione è presente viene letta la lista di eccezioni da catturare nella istruzione except (la lista è una tuple e va racchiusa tra parentesi e ogni eccezione va separata da una virgola: se si vuole cattutare una sola eccezione le parentesi non sono necessarie); in ogni caso l'esecuzione del codice tra try e except viene interrotta all'istruzione che ha generato l'eccezione.
- Se l'eccezione è presente nella lista, viene eseguito il codice che segue except.
- Se l'eccezione non viene catturata viene passata all'eventuale coppia di condizioni try/except di livello superiore; se nessuno la cattura, il programma esce segnalando il problema.
try: . . . except IOError, messaggio: print 'Errore di input/output:', messaggio except ZeroDivisionError, messaggio: print 'Divisione per zero:', messaggioSe l'istruzione except non ha nessun argomento tutte le eccezioni sono catturate: questa possibilità va usata con estrema cautela, essendo possibile che nasconda reali problemi del programma. Molte eccezioni hanno associate un valore sotto forma di stringa usato per fornire una descrizione dettagliata di ciò che è successo: questo valore può essere catturato semplicemente ponendo come secondo argomento di except la variabile che lo conterrà (nel nostro esempio messaggio). Al posto dell'istruzione except è possibile usarne un'altra dal comportamento diverso: finally. Il codice dell'istruzione finally è eseguito sia che venga lanciata o meno una eccezione; dopo l'esecuzione di questo codice l'eccezione viene nuovamente lanciata e se non catturata da istruzioni except di livello superiore il programma esce (in pratica è utile per scrivere una volta sola alcune righe di codice che devono necessariamente essere eseguite anche nel caso il programma incontri un errore).
Ultima nota da segnalare per quanto riguarda la raccolta di una eccezione è che in caso questa venga generata in una parte di codice esterna alle istruzioni try/except o try/finally (ad esempio in una funzione chiamata) queste non vengono catturate.
È possibile per l'utente lanciare una eccezione con l'istruzione:
raise nomeEccezione, 'Descrizione'dove nomeEccezione è chiaramente il nome dell'eccezione da lanciare e Descrizione è l'eventuale argomento.
Se ne ha necessità il programmatore può anche definire le proprie eccezioni; il modo più semplice è definire l'eccezione come una stringa la quale sarà usata come messaggio di errore. Esempio banale:
nuovoError = 'Il programma ha incontrato un problema' raise nuovoErrorDalla versione 1.5 in python le eccezioni sono state riscritte per essere classi; è ancora possibile utilizzare la vecchia sintassi vista sopra, ma è preferibile seguire il nuovo design. Tutte le eccezioni standard sono state inquadrate in un albero logico nel modulo exceptions alla base del quale c'è la classe Exception dal quale l'utente può far derivare le proprie eccezioni in questo modo:
class MyError(Exception): """Mia classe di errori""" passDa questa è possibile creare istanze:
primotipoError = MyError('Un tipo di errore')Che potrà essere invocato con le forme equivalenti:
raise primotipoError raise MyError, primotipoError raise MyError(primotipoError)Non è comunque obbligatorio derivare oggetti dalla classe; sono perfettamente lecite le chiamate:
raise MyError() raise MyError('Un altro tipo di errore')Di queste varie forme è preferibile utilizzare raise nomeIstanza o raise NomeClasse(argomenti); ultima cosa da ricordare è che la classe indicata nell'istruzione except blocca anche tutte le classi da questa derivate (ma non la classe o le classi da cui deriva).
Per maggiori informazioni sulle caratteristiche e sulla organizzazione delle eccezioni rimando alla documentazione del già citato modulo exceptions; sulle classi e loro proprietà torneremo nel prossimo articolo.
linea 7 | connessione = poplib.POP3('mail.ginopino.it')Creiamo una istanza dell'oggetto POP3.
Nelle librerie standard del python vi sono numerose definizioni di classi dalle quali è possibile derivare oggetti manipolabili con semplicità; per creare un nuovo oggetto è sufficiente la sintassi nomeoggetto = Classe() racchiudendo tra le parentesi eventuali argomenti richiesti. Nel nostro esempio abbiamo creato un oggetto chiamato connessione partendo dalla classe POP3 definita nel modulo poplib che richiedeva come argomento una stringa rappresentante il nome di un server di posta.
linea 8 | connessione.user('davide') linea 9 | connessione.pass_('la_mia_password')Richiamiamo dei metodi propri dell'oggetto sopra creato: in pratica ci connettiamo al server stabilito durante la creazione dell'oggetto connessione e inviamo in sequenza i comandi per identificarci come utente davide e per passargli la nostra password.
Una volta creato un oggetto è possibile sia manipolarne eventuali variabili sia eseguirne funzioni (dette in questo caso metodi) definite all'interno della classe a cui l'oggetto appartiene. Sempre con un occhio al nostro esempio abbiamo la successiva chiamata dei metodi user() e pass_() dell'oggetto connessione definiti nella classe POP3; in questo caso entrambi i metodi non hanno alcun valore di ritorno e richiedono un solo argomento.
linea 10 | nmex, sz = connessione.stat()Raccogliamo delle statistiche fornite dal mail server che raccoglie la nostra posta.
Come era logico aspettarsi molti metodi restituiscono
argomenti che possiamo raccogliere assegnandoli ad una
variabile; un metodo o una funzione può restituire
anche più di un argomento: in questo caso possiamo
decidere di raccogliere i vari argomenti in variabili
separate o in una sola sotto forma di tuple; in ogni caso
è sempre possibile ignorare il valore di ritorno di
una funzione semplicemente non raccogliendone il
risultato.
Come avrete notato le variabili non sono tipizzate e
possono essere dichiarate al momento dell'uso.
linea 11 | connessione.quit()Chiudiamo la connessione al server.
linea 12 | return nmex, szLa nostra funzione controlla_posta() restituisce i due valori raccolti dal server.
Una funzione può restituire uno o più valori semplicemente usando l'istruzione return seguita dai valori di ritorno. Una funzione che non comprenda un return non restituisce alcun valore (o meglio, restituisce None, oggetto non troppo diverso dal NULL del C/C++) è comunemente chiamata procedura.
linea 16 | while 1:Iniziamo un ciclo infinito.
Come avrete notato dall'indentazione di questa
istruzione il codice inizia ad essere eseguito proprio da
questo punto, essendo l'istruzione che la precede allo
stesso livello (def controlla_posta():) una
definizione di funzione, la quale ovviamente non viene
eseguita immediatamente ma solo quando esplicitamente
richiamata.
A questo punto mi sembra d'obbligo addentrarci in un paio
di argomenti importanti: i valori di verità e le
istruzioni classiche della programmazione strutturata.
La verità è là fuori!
A costo di dire una banalità definiamo vero in python tutto ciò che non è falso. Per farla breve ecco un elenco di ciò che è falso:- 0 (di qualsiasi tipo esso sia: intero, float, etc.)
- None
- le sequenze vuote come: '' "" () [] {}
- istanze di classi definite dall'utente che abbiano definito il metodo __nonzero__() o il metodo __len__() in modo che questo ritorni 0
Il mio float è più grande del tuo!
Su tutti gli oggetti è possibile utilizzare i tipici operatori booleani; vediamone la sintassi:- x or y
- x and y
- not x
Su tutti gli oggetti sono anche possibili confronti; i
più comuni sono: < minore stretto,
<= minore uguale, > maggiore,
>= maggiore uguale, == uguale, != o
<> diverso e l'operatore is che ritorna
vero se l'oggetto specificato è del tipo richiesto
(la sua negazione è is not). Questi operatori
restituiscono sempre 0 per indicare falso e 1
per indicare vero.
Sono possibili anche confronti tra tipi diversi (per
esempio una stringa ed una lista), ma il loro output
è chiaramente arbitrario.
Probabilmente vi state chiedendo come possano essere
utilizzati gli operatori is e is not che in molti casi
possono tornare davvero comodi; per farlo dobbiamo
importare gli oggetti definiti nel modulo standard
types in questo modo:
from types import *A questo punto sarà possibile usare la funzione type() sull'oggetto di cui ci domandiamo la natura e confrontarne l'output tramite gli operatori is o is not con le definizioni di tipo importate dal modulo types. Ad esempio:
if type(variabile) is IntType: print 'la variabile è un intero'
if (no, Kipling non c'entra)
L'istruzione if funziona esattamente come ci si potrebbe aspettare; un esempio di codice dovrebbe essere sufficiente a chiarirne l'uso:if variabile > 1: print 'la variabile è maggiore di 1' # possono essere presenti zero o più elif, contrazione di else if elif variabile == 3: print 'la variabile vale 3' else: print 'la variabile vale', variabile
while (cicli)
Lo abbiamo visto: ripete il ciclo finché la condizione resta vera.Nei cicli while e for (che analizzeremo qui sotto) è possibile usare le istruzioni break e continue che rispettivamente fanno uscire dal ciclo e interrompono l'attuale iterazione del ciclo per riprenderlo dall'inizio con l'iterazione successiva. Altra istruzione interessante da applicare a questi due cicli è else il cui codice viene eseguito quando la condizione di un ciclo while diventa falsa o quando viene esaurita la lista di un ciclo for (in ogni caso questo codice non verrà eseguito se si esce dai cicli con un break). Piccolo esempio:
x = 0 while x < 10: x = x + 1 else: print 'x è ora maggiore di 10'
for (iterazioni)
I cicli for vengono ripetuti per ogni oggetto della sequenza passata come argomento, assegnando alla variabile specificata il valore dell'oggetto. Questo comportamento è piuttosto diverso da quello del C o del Pascal e simile a quello del for nella shell bash. Un esempio chiarificatore:for variabile in 'cane', 'gatto', 4, 5: print 'Variabile:', variabile
Variabile: cane Variabile: gatto Variabile: 4 Variabile: 5
pass
Indica di non fare nulla: può essere usato in qualsiasi parte del programma (all'interno di classi, di funzioni, di cicli, etc.) dove la sintassi richieda una espressione ma non sia necessario compiere alcuna azione.def tipica_procedura_Microsoft(): """Non fa assolutamente nulla e non è documentata ;-)""" pass
linea 17 | try: . . . linea 22 | except KeyboardInterrupt:Catturiamo il ctrl+c.
Ricominciamo ora ad analizzare il codice del nostro
piccolo esempio: abbiamo già visto le istruzioni
try/except, qui le applichiamo allo stesso modo ora che
siamo dentro un ciclo infinito in cui l'unico modo per
uscirne (a meno di altri errori nel funzionamento del
programma o del collegamento al server) è l'uso
della combinazione ctrl+c che uccide il processo corrente.
Naturalmente il programma verrebbe ugualmente terminato se
non catturassimo questo interrupt, ma in quel caso verrebbe
stampata a video l'indicazione dell'eccezione generata, e
non è certo piacevole da vedere; grazie a questa
istruzione except invece possiamo chiudere il programma con
un messaggio di saluto e chiamando poi la funzione
exit() del modulo sys che serve a chiudere
con delicatezza il programma specificando un valore di
ritorno.
C'è da notare una questione piuttosto subdola
già accennata durante la trattazione delle eccezioni
e che qui vediamo nella pratica: con ogni
probabilità quando premeremo ctrl+c il programma
starà eseguendo l'istruzione sleep, ma se per
pura sfortuna cercassimo di chiuderlo mentre il programma
sta eseguendo la chiamata alla funzione
controlla_posta() vedremmo comparire a video il
messaggio di errore dell'eccezione, non essendo questa
catturata anche durante l'esecuzione della funzione stessa;
se volessimo migliorare il codice potremmo sostituire nella
riga 13 (poplib.socket.error,
poplib.error_proto) con (poplib.socket.error,
poplib.error_proto, KeyboardInterrupt).
linea 18 | numero_messaggi, dimensione = controlla_posta()Chiama la funzione controlla_posta() precedentemente definita e immagazzina i valori di ritorno nelle variabili numero_messaggi e dimensione di chiaro significato; non credo ci sia altro da dire su questo passaggio, essendo argomenti già trattati.
linea 19 | if numero_messaggi > 0:Se il numero dei messaggi indicato dal server è maggiore di 0, allora...
linea 20 | print 'Numero messaggi:', numero_messaggi, 'Dimensioni:', dimensioneStampa il numero di messaggi e la dimensione in byte dei messaggi nella nostra casella.
print argomento1, argomento2, ...è utile per alternare stringhe con numerici e altri tipi di dati, ma non si presta molto bene per output più complessi (di cui spero di parlare nel prossimo articolo) in cui spesso è necessario prima convertire valori numerici in stringhe racchiudendoli tra `apici singoli inversi` e concatenare due stringhe senza lasciare uno spazio tra loro, effetto ottenibile sostituendo le virgole che separano gli argomenti con un +. Se è necessario inserire il risultato di una funzione è possibile usare anche una sintassi più chiara con non la separazione degli argomenti tramite virgole:
print 'Prima funzione: %s Seconda funzione: %s' % (funz1(), funz2())Dove %s è un segnaposto per il risultato della funzione.
Oltre che da apici singoli le stringhe possono anche essere racchiuse tra doppi apici; in entrambi i casi i caratteri speciali vanno scritti tramite le classiche sequenze di escape (ad esempio il ritorno a capo sarà \n). Se si vuole un output su più linee senza dover scrivere caratteri di escape è possibile racchiudere la stringa tra tripli doppi apici, ad esempio:
print """stringa molto lunga con a capo"""Come avrete notato in ogni caso print aggiunge un ritorno a capo finale; se fosse necessario un controllo più fine sull'output si dovrà usare il metodo write sui descrittori di file stdout e stderr definiti nel modulo sys. Ad esempio (notate che il ritorno a capo è stato scritto esplicitamente):
sys.stdout.write('Output su standard output\n') sys.stderr.write('Output su standard error\n')
linea 21 | time.sleep(600)Invoca sleep definita nel modulo precedentemente importato time; questa procedura sospende l'esecuzione del programma per lo specificato numero di secondi (può ricevere anche un float, se è necessaria una precisione maggiore).
A questo punto, se il programma non è stato interrotto dall'utente o da un qualche errore, il ciclo while riprenderà nuovamente fino alla fine del mondo o allo spegnimento del computer.
Conclusioni e prossimi capitoli
Finisce qui l'introduzione a python; spero abbiate ora una vaga idea di come funziona e basi sufficienti per scrivere alcuni piccoli script. Non crediate però che sia tutto qui: come detto nella presentazione python è un linguaggio ad oggetti adatto anche per progetti di notevoli dimensioni; nella prossima puntata (no, non ho idea di quando sarà pronta) mi inventerò un programma ad oggetti in cui si faccia uso di classi, input/output da/su file e tastiera, tipi di dati complessi e chissà cosa altro mi verrà in mente.Se avete idee molto brillanti su quali argomenti dovrei trattare, come farlo, spunti interessanti e commenti a questo articolo contattatemi pure a alberanid@libero.it.
Altra documentazione e link
Tutta la documentazione che vi serve dovrebbe già essere presente sul vostro sistema nella directory /usr/doc/python o /usr/share/doc/python; molto utile il Tutorial e fondamentale la Library Reference dove sono descritte dettagliatamente tutte le librerie standard. Nella sottodirectory examples vi sono numerosi script da cui potrete prendere spunto (attenzione: la documentazione e gli esempi potrebbero essere in pacchetti separati di nome python-doc e python-examples).Per quanto riguarda i link, per ora non vi è molto di specifico da segnalare se non:
- python.org: il sito ufficiale.
- web.tiscalinet.it/python/: sito italiano.
- comp.lang.python: newsgroup su python.
- comp.lang.python.announce: annunci riguardanti python.
Note
1 - Prima che ci perdiate il sonno: il nome deriva dai mitici Monty Python e non ha nulla a che fare con i rettili.
2 - Ok, formalizziamoci: come di certo saprete nei linguaggi compilati (come il C) il sorgente è elaborato da un compilatore che si occupa di crearne codice eseguibile sull'architettura target; i programmi dei linguaggi interpretati (Basic, bash) vengono invece letti ed eseguiti una linea alla volta: ciò risulta molto lento e quindi poco adatto a programmi complessi; per ovviare a questi inconvenienti nei linguaggi pseudocompilati il codice viene letto completamente sin dall'inizio e ne viene creata al volo una "immagine" in un linguaggio intermedio tra il solo testo dello script ed il codice dipendente dall'architettura; l'interprete eseguirà poi questo pseudocodice in maniera molto più veloce che leggendo lo script line per linea.
3 - Python è già disponibile per molte versioni di Unix, DOS, Windows, Windows NT, OS/2, Mac, Amiga e altre piattaforme ancora.