Translation(s): English - Italiano - Português


Questo è un riassunto del tutorial su Python tenuto in IRC nel canale #debian-women l'11 febbraio 2006.

Questa versione del tutorial non è un'esatta trascrizione del registro di IRC; espande un po' alcuni punti, perciò può essere interessante da leggere anche se si è partecipato alla sessione tutorial IRC.

Il tutorial è strutturato su esempi che sono stati spiegati, ciascuno seguito da domande e risposte e da una discussione.

Informazioni su Python in generale

Dalla FAQ di Python:

Python è un linguaggio di programmazione interpretato, interattivo e orientato agli oggetti. Incorpora moduli, eccezioni, creazione di tipi dinamica, classi e tipi di dati dinamici veramente di alto livello.

Interpretato significa, in pratica, che si può semplicemente eseguire programmi Python memorizzati in file senza dover prima compilarli; quindi per questo aspetto è simile agli script di shell e diverso dai programmi in C.

Interattivo significa che si può avviare l'interprete Python e iniziare a fornirgli istruzioni, una alla volta, ed esso le eseguirà e stamperà ogni risultato. Coloro che hanno familiarità con REPL (Read-Eval-Print Loop) di Lisp si troveranno in acque conosciute. Stessa cosa vale per il BASIC.

Orientato agli oggetti significa che Python favorisce la programmazione orientata agli oggetti, ma non forza ad usarla. Python è più lasco per ciò che riguarda i propri paradigmi rispetto, ad esempio, a Java.

Tra le altre cose menzionate nell'elenco della FAQ, la "creazione di tipi dinamici" è probabilmente la più interessante. È un po' uno shock per coloro che conoscono solo linguaggi come il C o Java, che hanno tipi statici: le variabili hanno un tipo che è dichiarato esplicitamente e perciò anche ogni espressione ha un tipo che può essere analizzato al momento della compilazione. Il compilatore quindi può trovare errori prima ancora che il programma inizi.

Con la creazione dinamica dei tipi, le variabili non hanno un tipo, i valori lo hanno. Una variabile può essere "collegata" a diversi tipi di variabili in tempi diversi e perciò tutti i controlli sui tipi sono fatti al momento dell'esecuzione. Ciò rende le cose più facili da fare, ma può rendere più difficile l'individuazione di errori nei tipi.

I tipi dinamici sono tendenzialmente buoni per programmi medio-piccoli e per sviluppo e prototipazione rapidi. I tipi statici sono adatti a programmi grandi.

Python è spesso descritto come un linguaggio di scripting, ma ciò non significa che non sia un linguaggio generico adatto ad ogni scopo. Python, come Perl, è usato spesso per creare soluzioni veloci ed è adatto a tale scopo dato che è di alto livello e interpretato ed ha alcune belle caratteristiche e librerie per certi tipi di compiti correlati con l'amministrazione di sistema. Allo stesso tempo. è spesso usato per lo sviluppo delle cosiddette applicazioni reali.

Collegamenti

Il programma "hello world"

   1 # Salvare in un file "hello.py" ed eseguirlo usando "python hello.py"
   2 print "hello, world"

Salvare le righe precedenti in un file chiamato "hello.py" ed eseguirlo con il comando "python hello.py". Se funziona, allora significa che si ha un'installazione di Python funzionante e si sa come usarla.

La prima riga è un commento che inizia con un carattere cancelletto ("#") e continua fino alla fine della riga.

La seconda riga è una semplice istruzione che stampa una stringa, più un carattere di nuova riga. "print" è il modo più semplice per produrre output sullo standard output. Si può stampare qualsiasi numero o valore, basta separarli con virgole e ci saranno spazi tra i valori stampati.

Argomenti della riga di comando

   1 #Eseguire questo come python hello2.py proprio_nome
   2 import sys
   3 print "ciao", sys.argv[1]

Qui è mostrato un modo per importare un modulo di libreria e un modo per accedere agli argomenti nella riga di comando. "sys" è uno dei moduli della libreria Python standard. In quel modulo c'è un array, o meglio una lista, chiamata argv, che contiene gli argomenti nella riga di comando del programma Python, in modo simile all'argomento argv della funzione principale nel C.

Le liste (o gli array) iniziano l'indicizzazione da zero. Perciò, sys.argv[0] è il primo argomento nella riga di comando; come in C è il nome del programma che si sta eseguendo. sys.argv[1] è il primo reale argomento. Notare che, dato che Python ha tipi dinamici, non è necessario che gli elementi delle liste siano dello stesso tipo.

Eseguire il programma come "python hello2.py bellezza" ed esso stamperà "ciao, bellezza".

Se non si fornisce un argomento sulla riga di comando, il programma cercherà di usare sys.argv[1] mentre esso non esiste e ciò causerà un errore durante l'esecuzione: un'eccezione, e l'interprete Python stamperà un lungo e terribile messaggio di errore, simile a:

liw@esme$ python hello2.py
greetings,
Traceback (most recent call last):
File "hello2.py", line 3, in ?
print "greetings,", sys.argv[1]
IndexError: list index out of range

Il backtrace dell'eccezione ha un record (due righe) per ciascuna voce nello stack delle chiamate, con il luogo dove l'eccezione si è verificata alla fine (cioè, il programma principale in cima).

Leggendolo attentamente e analizzando ciò che era stato chiamato e dove, si può (solitamente!) capire ciò che è andato storto. È possibile per un programma catturare eccezioni.

if

Gli esempi "hello, world" continuano ad essere incredibilmente affascinanti.

   1 #Eseguire come python hello3.py proprio_nome
   2 import sys
   3 print "ciao,",
   4 if len(sys.argv) == 2:
   5     print sys.argv[1]
   6 else:
   7     print "persona senza nome"

Una virgola dopo l'ultimo argomento da stampare con "print" eviterà la stampa di un carattere di nuova riga.

"len(pippo)" restituisce la lunghezza della lista "pippo", cioè il numero di elementi contenuti in essa. Gli indici, perciò, vanno da 0 a len(pippo)-1. len() è una funzione molto veloce a tempo costante.

Qui len viene usato per controllare che sia stato fornito un argomento nella riga di comando, e se ciò non è vero il saluto viene sostituito con uno generico.

L'altra cosa importante di questo esempio è l'istruzione "if". E qui viene insegnato anche l'uso in Python dei rientri per marcare i blocchi.

Le parti "then" (allora) e "else" (altrimenti) della istruzione "if" (se) sono entrambe marcate con un rientro maggiore rispetto all'istruzione "if". Python non ha un modo esplicito per marcare i blocchi, ciò viene sempre fatto con i rientri. Un blocco è una serie di istruzioni con lo stesso rientro; i commenti e le righe vuote vengono ignorati, naturalmente.

I caratteri di tabulazione vengono espansi in modo predefinito agli 8 caratteri, ma ciò è configurabile. L'uso di un valore diverso probabilmente causa problemi quando si condivide il codice con altri. I programmatori Python preferiscono di solito usare solamente gli spazi ed evitare del tutto le tabulazioni.

"if" e altre istruzioni che iniziano blocchi, terminano con un carattere due punti. Questo è un problema di stile. Mettere i due punti è necessario e occasionalmente può aiutare il parser a trovare errori di sintassi.

È possibile inserire istruzioni diverse su una stessa riga, separandole con un carattere di punto e virgola, ma ciò è considerato un pessimo stile di scrittura.

while

Un altro esempio "hello".

   1 # Eseguire come: python hello4.py nome1 nome2 nome3 ...
   2 import sys
   3 print "ciao,",
   4 
   5 if len(sys.argv) == 1:
   6     print "persona senza nome"
   7 elif len(sys.argv) == 2:
   8     print sys.argv[1]
   9 else:
  10     i = 1
  11     last_index = len(sys.argv) - 1
  12     while i < last_index:
  13         print sys.argv[i] + ",",
  14         i = i + 1
  15     print "and", sys.argv[last_index]

In questo esempio vengono insegnati: le variabili, "elif" e "while". Le variabili funzionano in modo simile a ciò che probabilmente ci si aspetta. Le variabili non vengono dichiarate, ma è un errore usare un variabile a cui non è stato ancora assegnato un valore nell'ambito locale o in un ambito che lo comprende.

Un'assegnazione crea una variabile locale (è possibile usare variabili globali, ma per ora quest'argomento non viene trattato). Perciò un errore di battitura nell'ultima istruzione del ciclo while (mentre) nell'esempio precedente che risultasse in "i = j + 1" farebbe sì che Python causi un'eccezione, ma "j = i + 1" funzionerebbe, causando forse un ciclo infinito?

Quando si dice che "ad una variabile è assegnato un valore", ciò che si intende in realtà è che la variabile ottiene un riferimento al valore. Tutte le variabili sono riferimenti.

"elif" è una contrazione di "else if" (altrimenti se) e dovrebbe essere abbastanza chiaro. In Python non esiste un'istruzione "switch", si usa invece una lunga istruzione "if: ... elif: ... elif: ... else: ..."

Tutti i consueti operatori interi funzionano:

 +, -, *, /, %, <, >, <=, >=, ==, !=.

Non ci sono operatori ++ o --, e quelli += e simili sono usati solo nelle istruzioni di assegnazione (le assegnazioni non sono mai espressioni in Python).

Alcuni degli operatori sono funzionanti anche per altri tipi. Per esempio, + funziona anche come concatenazione di stringhe quando entrambi gli operandi sono stringhe.

Per "if", "while" e altri contesti in cui è richiesto un valore booleano, i valori False, 0, 0.0, "" e None, più alcuni altri valori "vuoti" sono trattati come falso, tutto il resto come vero.

for

Ancora saluti.

   1 # Eseguire come: python hello5.py nome1 nome2 nome3 ...
   2 import sys
   3 print "ciao,",
   4 
   5 if len(sys.argv) == 1:
   6     print "persona senza nome"
   7 elif len(sys.argv) == 2:
   8     print sys.argv[1]
   9 else:
  10     for name in sys.argv[1:-1]:
  11         print name + ",",
  12     print "e", sys.argv[-1]

La cosa nuova in questo esempio è il ciclo "for", che fa un'iterazione su una sequenza di valori, come una lista. A "name" viene assegnato a turno il valore di ogni argomento nella riga di comando e poi viene eseguito il blocco all'interno di "for". Questo tende ad essere più comodo dell'indicizzazione esplicita con "while".

L'altra cosa interessante è l'uso di porzioni. Le porzioni sono un modo di creare una nuova lista a partire dagli elementi di un'altra: una sottosezione di un'altra lista. Data una lista "pippo", "pippo[i]" è l'elemento con indice i, "pippo[a:b]" è una nuova lista con tutti gli elementi a partire dall'indice a fino all'indice b escluso. Per rendere le cose ancora più interessanti, i, a e b possono essere tutti negativi e in quel caso indicano gli indici a partire dalla fine della lista; perciò "pippo[-1]" è l'ultimo elemento. "sys.argv[1:-1]", quindi, rappresenta tutti gli argomenti nella riga di comando dal primo dopo il nome di programma, fino all'ultimo escluso.

Gli indici a e b possono anche essere omessi; in quel caso, viene usata la fine corrispondente della lista. "pippo[a:]" è tutto ciò che va dall'indice a alla fine della lista, "foo[b:]" è tutto ciò che va dall'inizio della lista all'indice b escluso. "foo[:]" è una copia dell'intera lista.

Funzioni

Non c'è mai fine ai saluti, vero?

   1 # Eseguire come: python hello6.py nome1 nome2 nome3 ...
   2 import sys
   3 
   4 def greet(greeting, names):
   5     print greeting + ",",
   6 
   7     if not names:
   8         print "persona senza nome"
   9     elif len(names) == 1:
  10         print names[0]
  11     else:
  12         for name in names[:-1]:
  13             print name + ",",
  14         print "e", names[-1]
  15 
  16 greet("ciao", sys.argv[1:])

Questo esempio mostra come viene definita una funzione. Notare che i nomi degli argomenti (se ci sono) vengono dichiarati, ma non viene dichiarato il loro tipo e nemmeno il tipo restituito. Tutta la definizione dei tipi in Python è dinamica.

Notare anche che la funzione ottiene un elenco di nomi da salutare e sys.argv inizia con il nome del programma, per cui il programma lo elimina usando una porzione (sottolista) quando chiama la funzione.

Hashbang

Il repertorio di programmi hello world è infinito!

   1 #!/usr/bin/python
   2 
   3 import sys
   4 
   5 def greet(greeting, names):
   6     print greeting + ",",
   7 
   8     if not names:
   9         print "persona senza nome"
  10     elif len(names) == 1:
  11         print names[0]
  12     else:
  13         for name in names[:-1]:
  14             print name + ",",
  15         print "e", names[-1]
  16 
  17 def main():
  18     greet("ciao", sys.argv[1:])
  19 main()

Questo è il modo in cui si crea uno script Python che può essere eseguito come qualsiasi altro comando, senza dover fare iniziare il comando con "python". Salvare il programma in un file "hello7", modificare i permessi con "chmod +x" e poi eseguirlo con "./hello7".

Il programma principale di un programma Python solitamente è messo in una funzione (spesso chiamata "main"). Tale funzione è poi chiamata direttamente o, meglio, in questo modo:

   1 if __name__ == "__main__":
   2     main()

"__name__" è una speciale variabile Python che ha il valore "__main__" se il file Python viene eseguito direttamente. Ciò permette al file di essere usato come modulo Python (cioè con "import") senza invocare il suo programma principale. Questo può anche essere usato per invocare i test di unità.

I/O

Basta con l'essere educati e salutare.

   1 #!/usr/bin/python
   2 
   3 import sys
   4 
   5 line_count = 0
   6 while True:
   7     line = sys.stdin.readline()
   8     if not line:
   9         break
  10     line_count += 1
  11 
  12 sys.stdout.write("%d righe\n" % line_count)

Questo programma conta il numero di righe nello standard input.

"sys.stdin", "sys.stdout" e "sys.stderr" sono oggetti file che corrispondono ai flussi dello standard input, output e error.

Gli oggetti file hanno un metodo ".readline()" che legge e restituisce la riga successiva, incluso il carattere di nuova riga, oppure una stringa vuota se raggiunge la fine del file (EOF).

In modo analogo, ".write()" è un metodo per oggetto file che scrive una stringa nel file; non aggiunge un carattere di nuova riga.

"if not line" testa se la variabile line è falsa o meno; se è falsa, allora è la stringa vuota (dato che ha un valore stringa). Perciò la condizione è vera alla fine del file. Poi "break" fa saltare fuori dal ciclo più interno.

Il modello "while True: data = f.read(); if not data: break" è un metodo comune per avere input in un ciclo.

Quando il primo operando dell'operatore % è una stringa, funziona in modo simile a sprintf in C. Il primo operando agisce come stringa di formato e "%s" in esso viene sostituito da un valore stringa, "%d" da un valore intero, ecc.

I valori vengono presi dal secondo operando che può essere un valore singolo, se c'è solo un %qualcosa nella stringa di formato, oppure una sequenza di valori all'interno di parentesi se ce ne sono diversi.

Manipolazione di stringhe

Non si torna a hello, world.

   1 #!/usr/bin/python
   2 
   3 import sys
   4 
   5 def count_words(str):
   6     word_count = 0
   7     i = 0
   8     in_word = False
   9     while i < len(str):
  10         c = str[i]
  11         is_word_char = (c >= "a" and c <= "z") or (c >= "A" and c <= "Z")
  12         if in_word:
  13             if not is_word_char:
  14                 in_word = False
  15         else:
  16             if is_word_char:
  17                 in_word = True
  18                 word_count += 1
  19         i += 1
  20     return word_count
  21 
  22 def main():
  23     line_count = 0
  24     word_count = 0
  25     byte_count = 0
  26 
  27     while True:
  28         line = sys.stdin.readline()
  29         if not line:
  30             break
  31         byte_count += len(line)
  32         line_count += 1
  33         word_count += count_words(line)
  34 
  35     sys.stdout.write("%d parole, %d righe, %d byte\n" %
  36                      (word_count, line_count, byte_count))
  37 
  38 main()

Questo programma conta le parole, definite come sequenze di lettere o cifre. È l'esempio più esteso visto fino ad ora ed è anche molto, molto brutto. Verrà reso più bello in seguito, però.

Le stringhe possono essere usate (in parte) come le liste: "len(str)" è la lunghezza di una stringa, "str[i]" è il carattere all'indice i, anche "str[a:b]" funziona come atteso. Non esiste un tipo separato per i caratteri, sono usate invece le stringhe di un solo carattere.

Le stringhe possono essere confrontate con <, <= e così via; il confronto è basato sui valori dei byte (dato che le stringhe sono stringhe di byte; si parlerà di Unicode in seguito).

L'ultima riga di main() mostra un modo di estendere istruzioni Python su più righe: se un'espressione tra parentesi è troppo lunga, suddividerla nella riga successiva e tutto funzionerà automaticamente. L'altro modo è di usare una barra inversa alla fine della riga.

La parte bruttissima di questo codice è il fatto che è molto specifico per ASCII, quando dovrebbe invece essere sensibile alla localizzazione; inoltre è inutile usare "while" per fare reiterazioni sui caratteri in una stringa quando anche "for" funziona.

Stringhe Unicode

Avvertimento: l'autore non è un mago dell'uso di Unicode, né in generale né in Python.

I caratteri Unicode sono più grandi di 8 bit (e non importa sapere esattamente quanto siano grandi quando si usa Python). Python ha un tipo di stringa distinto per le stringhe Unicode. Funzionano in modo praticamente identico alle stringhe normali (che sono stringhe di byte), ma per l'I/O è necessario convertirle da e verso stringhe di byte usando qualche tipo di codifica. La codifica dipende da vari fattori, ma spesso va bene usare la codifica basata sulla localizzazione attuale.

Notare che una stringa Unicode Python non è una stringa UTF-8. UTF-8 è una delle codifiche usate per l'I/O (e per la memorizzazione).

Nel codice sorgente, 'u"Copyright \u00A9 2006 Lars Wirzenius"' è una stringa Unicode contenente il carattere del copyright. Non si possono scrivere caratteri non ASCII nel codice sorgente Python a meno di non dire all'interprete Python quale codifica e insieme di caratteri siano usati (e l'autore non sa come farlo).

"sys.stdin.readline" restituisce una stringa normale, che verrà qui chiamata "s". "s.decode(enc)" decodifica s in una stringa Unicode ("u") usando una qualche codifica. "u.encode(enc)" codifica nella direzione opposta, da Unicode verso una stringa normale. "enc" può essere, ad esempio, "utf-8". "locale.getpreferredencoding()" restituisce la codifica preferita per la localizzazione attuale.

Rivisitazione del conteggio di parole

Ecco di nuovo il conteggio di parole applicando ciò che è stato imparato.

   1 #!/usr/bin/python
   2 
   3 import locale
   4 import sys
   5 
   6 def count_words(str):
   7 
   8     word_count = 0
   9     in_word = False
  10     for c in str:
  11         if in_word and not c.isalnum():
  12             in_word = False
  13         elif not in_word and c.isalnum():
  14             in_word = True
  15             word_count += 1
  16     return word_count
  17 
  18 def main():
  19     locale.setlocale(locale.LC_ALL, "")
  20 
  21     line_count = 0
  22     word_count = 0
  23     char_count = 0
  24 
  25     while True:
  26         line = sys.stdin.readline()
  27         if not line:
  28             break
  29         line = line.decode(locale.getpreferredencoding())
  30         char_count += len(line)
  31         line_count += 1
  32         word_count += count_words(line)
  33 
  34     sys.stdout.write("%d parole, %d righe, %d caratteri\n" %
  35                      (word_count, line_count, char_count))
  36 
  37 main()

In aggiunta a quanto discusso precedentemente per l'Unicode, è necessaria la riga 'locale.setlocale(locale.LC_ALL, "")' per attivare le impostazioni localizzate.

Altro divertimento con le parole: stampare tutte le parole

Ecco come stampare parole.

   1 #!/usr/bin/python
   2 
   3 import locale
   4 import sys
   5 
   6 def split_words(str):
   7     words = []
   8     word = None
   9     for c in str + " ":
  10         if word:
  11             if c.isalnum():
  12                 word += c
  13             else:
  14                 words.append(word)
  15                 word = None
  16         else:
  17             if c.isalnum():
  18                 word = c
  19     return words
  20 
  21 def main():
  22     locale.setlocale(locale.LC_ALL, "")
  23     encoding = locale.getpreferredencoding()
  24 
  25     while True:
  26         line = sys.stdin.readline()
  27         if not line:
  28             break
  29         line = line.decode(encoding)
  30         for word in split_words(line):
  31             sys.stdout.write("%s\n" % word.encode(encoding))
  32 
  33 main()

Una lista vuota viene scritta come "[]". Una lista non vuota verrebbe scritta usando: '[1, 2, 3, "ciao"]'. "list.append(item)" modifica la lista al volo e aggiunge un nuovo elemento alla fine. Le liste possono venir concatenate: "[1,2] + [3,4]" dà "[1,2,3,4]".

La funzione split_words crea nuove liste (e nuove stringhe) indiscriminatamente, non sono rilasciare in alcun punto del programma; Python ha la garbage collection, che è una cosa molto utile da avere.

La parte 'str + " "' in split_words serve per garantire che ci sia un carattere non-isalnum, in modo che se la riga finisce con una parola (senza carattere di nuova riga alla fine) viene comunque contata correttamente.

Frequenze delle parole: dizionari!

Ecco come contare le frequenze delle parole.

   1 #!/usr/bin/python
   2 
   3 import locale
   4 import sys
   5 
   6 def split_words(str):
   7     words = []
   8     word = None
   9     for c in str + " ":
  10         if word:
  11             if c.isalnum():
  12                 word += c
  13             else:
  14                 words.append(word)
  15                 word = None
  16         else:
  17             if c.isalnum():
  18                 word = c
  19     return words
  20 
  21 def main():
  22     locale.setlocale(locale.LC_ALL, "")
  23     encoding = locale.getpreferredencoding()
  24 
  25     counts = {}
  26 
  27     while True:
  28         line = sys.stdin.readline()
  29         if not line:
  30             break
  31         line = line.decode(encoding)
  32         for word in split_words(line):
  33             word = word.lower()
  34             if counts.has_key(word):
  35                 counts[word] += 1
  36             else:
  37                 counts[word] = 1
  38 
  39     words = counts.keys()
  40     words.sort()
  41     for word in words:
  42         sys.stdout.write("%d %s\n" % (counts[word], word.encode(encoding)))
  43 
  44 main()

È stato modificato il programma principale ("main"). Le tabelle hash di Python (o "hash map") vengono chiamate dizionari. Un dizionario vuoto è: "{}". Uno non vuoto: '{ "pippo": 0, "pluto": 1 }'. "dizion[chiave]" è il valore memorizzato ad una data chiave. Le chiavi possono essere numeri, stringhe o vari altri tipi per i quali Python sa come calcolare un valore hash.

"dizion.has_key(chiave)" è Vero se "dizion[chiave]" esiste (vi è stato assegnato un valore). In alternativa "chiave in dizion".

"dizion.keys()" è una lista non ordinata di tutte le chiavi.

Il metodo per stringa ".lower()" la converte in caratteri minuscoli, restituendo una nuova stringa (quella originale non viene modificata; le stringhe non possono essere modificate in Python). Analogamente, ".upper()" converte in caratteri maiuscoli.

"list.sort()" ordina sul posto (la lista originale viene modificata, non restituisce la lista ordinata né nessun altro valore).

Alcuni esempi con classi

Ecco come vengono usati le classi e gli oggetti in Python.

   1 #!/usr/bin/python
   2 
   3 import locale
   4 import sys
   5 
   6 class WordFreqCounter:
   7 
   8     def __init__(self):
   9         self.counts = {}
  10 
  11     def count_word(self, word):
  12         word = word.lower()
  13         if self.counts.has_key(word):
  14             self.counts[word] += 1
  15         else:
  16             self.counts[word] = 1
  17 
  18     def print_counts(self, file):
  19         encoding = locale.getpreferredencoding()
  20         words = self.counts.keys()
  21         words.sort()
  22         for word in words:
  23             file.write("%d %s\n" %
  24                        (self.counts[word], word.encode(encoding)))
  25 
  26 def split_words(str):
  27     words = []
  28     word = None
  29     for c in str + " ":
  30         if word:
  31             if c.isalnum():
  32                 word += c
  33             else:
  34                 words.append(word)
  35                 word = None
  36         else:
  37             if c.isalnum():
  38                 word = c
  39     return words
  40 
  41 def main():
  42     locale.setlocale(locale.LC_ALL, "")
  43     encoding = locale.getpreferredencoding()
  44 
  45     counter = WordFreqCounter()
  46 
  47     while True:
  48         line = sys.stdin.readline()
  49         if not line:
  50             break
  51         line = line.decode(encoding)
  52         for word in split_words(line):
  53             counter.count_word(word)
  54 
  55     counter.print_counts(sys.stdout)
  56 
  57 main()

In questo esempio il dizionario è stato messo in una classe. In un programma così piccolo non fa molta differenza avere una classe personalizzata oppure un semplice dizionario, ma è stato fatto a scopo dimostrativo.

"class" inizia una definizione di classe. Una classe viene instanziata con "NomeClasse()" (con gli argomenti, se ci sono, per il costruttore dentro la parentesi).

I metodi sono definiti come funzioni all'interno della classe, cioè devono essere rientrati rispetto alla riga "class". I metodi sono intuitivi tranne che per il primo argomento, di solito chiamato "self", che è un riferimento alla istanza di classe (oggetto) per cui sono stati chiamati.

Perciò quando si chiama "counter.count_word(word)", il primo argomento del metodo ("self") è collegato a "counter" e il secondo argomento ("word") è collegato a "word" (nel contesto del chiamante).

Non esiste un modo implicito di fare riferimento ad altri metodi o attributi dell'oggetto o classe; si deve sempre passare da "self".

Il nome di metodo speciale "__init__" indica il costruttore. Viene chiamato quando l'oggetto è creato.

Semplificando un po', non ci sono controlli di accesso sugli attributi e i metodi degli oggetti Python. Tutto è "pubblico" secondo la terminologia C++.

Moduli

Prima il file wordstuff.py:

   1  import locale
   2 
   3 class WordFreqCounter:
   4 
   5     def __init__(self):
   6         self.counts = {}
   7 
   8     def count_word(self, word):
   9         word = word.lower()
  10         if self.counts.has_key(word):
  11             self.counts[word] += 1
  12         else:
  13             self.counts[word] = 1
  14 
  15     def print_counts(self, file):
  16         encoding = locale.getpreferredencoding()
  17         words = self.counts.keys()
  18         words.sort()
  19         for word in words:
  20             file.write("%d %s\n" %
  21                        (self.counts[word], word.encode(encoding)))
  22 
  23 def split_words(str):
  24     words = []
  25     word = None
  26     for c in str + " ":
  27         if word:
  28             if c.isalnum():
  29                 word += c
  30             else:
  31                 words.append(word)
  32                 word = None
  33         else:
  34             if c.isalnum():
  35                 word = c
  36     return words

e poi il file freq3.py:

   1 #!/usr/bin/python
   2 
   3 import locale
   4 import sys
   5 
   6 from wordstuff import WordFreqCounter, split_words
   7 
   8 def main():
   9     locale.setlocale(locale.LC_ALL, "")
  10     encoding = locale.getpreferredencoding()
  11 
  12     counter = WordFreqCounter()
  13 
  14     while True:
  15         line = sys.stdin.readline()
  16         if not line:
  17             break
  18         line = line.decode(encoding)
  19         for word in split_words(line):
  20             counter.count_word(word)
  21 
  22     counter.print_counts(sys.stdout)
  23 
  24 if __name__ == "__main__":
  25     main()

freq3.py è il programma principale e usa wordstuff.py come modulo, importando da esso solo alcuni nomi. A questi nomi si può fare riferimento senza farli precedere dal nome del modulo.

Ogni file Python è potenzialmente un modulo che può essere importato in un altro file. I moduli vengono cercati in $PYTHONPATH; vedere la documentazione per ulteriori dettagli. solitamente non ci si deve preoccupare di impostare $PYTHONPATH se le cose sono state installate nel modo canonico.

E ora?

Leggere il tutorial su python.org.

Sfogliare la documentazione di riferimento della libreria e divertirsi a provare qualsiasi cosa che si trovi interessante.

Scrivere programmi, leggere programmi.