Subsections


3. Un'introduzione informale a Python

Negli esempi seguenti, l'input e l'output sono distinguibili per la presenza o meno dei prompt (">>" e "... "): per sperimentare l'esempio è necessario digitare tutto quello che segue il prompt, quando esso compare; le righe che non iniziano con un prompt sono output dell'interprete. Si noti che se in un esempio compare un prompt secondario isolato su una riga significa che si deve introdurre una riga vuota; questo viene usato per terminare un comando che si estende su più righe.

Molti degli esempi di questo manuale, anche quelli immessi al prompt interattivo, presentano commenti. In Python i commenti iniziano con il carattere 'hash', "#" e continuano fino alla fine della riga. Un commento può comparire all'inizio di una riga, dopo degli spazi bianchi o dopo del codice, ma non dentro una stringa costante. Un carattere hash dentro una stringa costante è solamente un carattere hash.

Alcuni esempi:

# questo è il primo commento
SPAM = 1                 # e questo è il secondo
                         # ... e ora il terzo!
STRING = "# Questo non è un commento."


3.1 Usare Python come una calcolatrice

Proviamo con qualche semplice comando Python. Avviate l'interprete e si attendete il prompt primario, ">>". Non dovrebbe metterci molto.


3.1.1 Numeri

L'interprete si comporta come una semplice calcolatrice: si può digitare un'espressione ed esso fornirà il valore risultante. La sintassi delle espressioni è chiara: gli operatori +, -, * e / funzionano come nella maggior parte degli altri linguaggi (p.e. Pascal o C); le parentesi possono essere usate per raggruppare operatori e operandi. Ad esempio:

>>> 2+2
4
>>> # Questo è un commento
... 2+2
4
>>> 2+2  # e un commento sulla stessa riga del codice
4
>>> (50-5*6)/4
5
>>> # Una divisione tra interi restituisce solo il quoziente:
... 7/3
2
>>> 7/-3
-3

Come in C, il segno di uguale ("=") è usato per assegnare un valore ad una variabile. Il valore di un assegnamento non viene stampato:

>>> larghezza = 20
>>> altezza = 5*9
>>> larghezza * altezza
900

Un valore può essere assegnato simultaneamente a variabili diverse:

>>> x = y = z = 0  # Zero x, y e z
>>> x
0
>>> y
0
>>> z
0

Le operazioni in virgola mobile sono pienamente supportate; in presenza di operandi di tipo misto gli interi vengono convertiti in virgola mobile:

>>> 3 * 3.75 / 1.5
7.5
>>> 7.0 / 2
3.5

Anche i numeri complessi vengono supportati; per contrassegnare i numeri immaginari si usa il suffisso "j" o "J". I numeri complessi con una componente reale non nulla vengono indicati come "(real+imagj)", o possono essere creati con la funzione "complex(real, imag)".

>>> 1j * 1J
(-1+0j)
>>> 1j * complex(0,1)
(-1+0j)
>>> 3+1j*3
(3+3j)
>>> (3+1j)*3
(9+3j)
>>> (1+2j)/(1+1j)
(1.5+0.5j)

I numeri complessi vengono sempre rappresentati come due numeri in virgola mobile, la parte reale e quella immaginaria. Per estrarre queste parti da un numero complesso z si usino z.real e z.imag.

>>> a=1.5+0.5j
>>> a.real
1.5
>>> a.imag
0.5

Le funzioni di conversione in virgola mobile e intero (float(), int() e long()) non funzionano con i numeri complessi: non c'è alcun modo corretto per convertire un numero complesso in numero reale. Usate abs(z) per ottenere la sua grandezza (in virgola mobila) o z.real per ottenere la sua parte reale.

>>> a=3.0+4.0j
>>> float(a)
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: can't convert complex to float; use abs(z)
>>> a.real
3.0
>>> a.imag
4.0
>>> abs(a)  # sqrt(a.real**2 + a.imag**2)
5.0
>>>

In modo interattivo, l'ultima espressione stampata è assegnata alla variabile _. Questo facilita i calcoli in successione quando si sta usando Python come calcolatrice da tavolo, ad esempio:

>>> tassa = 12.5 / 100
>>> prezzo = 100.50
>>> prezzo * tassa
12.5625
>>> prezzo + _
113.0625
>>> round(_, 2)
113.06
>>>

Questa variabile dev'essere trattata dall'utente come di sola lettura. Non le si deve assegnare esplicitamente un valore, si creerebbe una variabile locale indipendente con lo stesso nome che maschererebbe la variabile built-in ed il suo comportamento particolare.


3.1.2 Stringhe

Oltre ai numeri, Python può anche manipolare stringhe, che possono essere espresse in diversi modi. Possono essere racchiuse tra apici singoli o virgolette:

>>> 'spam eggs'
'spam eggs'
>>> 'doesn\'t'
"doesn't"
>>> "doesn't"
"doesn't"
>>> '"Yes," he said.'
'"Yes," he said.'
>>> "\"Yes,\" he said."
'"Yes," he said.'
>>> '"Isn\'t," she said.'
'"Isn\'t," she said.'

Le stringhe costanti possono estendersi su più righe in modi diversi. Si possono scrivere lunghe righe usando le barre oblique inverse (NdT: il cosiddetto ``escape'') come ultimo carattere di riga, questo indicherà che la riga successiva sarà in realtà la logica continuazione della precedente:

ciao = "Questa è una stringa abbastanza lunga che contiene\n\
parecchie righe di testo proprio come si farebbe in C.\n\
    Si noti che gli spazi bianchi all'inizio della riga sono\
 significativi."

print ciao

Si noti che il carattere di fine riga deve sempre essere inserito in una stringa usando \n; il carattere di fine riga successivo, composto dalla barra obliqua inversa viene ignorato. L'esempio verrà quindi stampato così:

Questa è una stringa abbastanza lunga che contiene
parecchie righe di testo proprio come si farebbe in C.
    Si noti che gli spazi bianchi all'inizio della riga sono significativi.

Se si volesse comporre una stringa letterale ``raw'', comunque, la sequenza \n non verrebbe convertita nel fine riga e, insieme alla barra obliqua inversa alla fine della riga del sorgente, si ritroverebbero entrambe le sequenze come nella stringa data. Quindi, l'esempio:

ciao = r"Questa è una stringa abbastanza lunga che contiene\n\
parecchie righe di testo proprio come si farebbe in C."

print ciao

stamperebbe:

Questa è una stringa abbastanza lunga che contiene\n\
parecchie righe di testo proprio come si farebbe in C.

Oppure le stringhe possono essere circondate da un paio di virgolette o apici tripli corrispondenti: """ o '''. Non è necessario proteggere i caratteri di fine riga quando si usano le triple virgolette, questi verranno inclusi nella stringa.

print """
Uso: comando [OPZIONI] 
   -h                        Visualizza questo messaggio
   -H hostname               Hostname per connettersi a
"""

produrrà il seguente output:

Uso: comando [OPZIONI] 
   -h                        Visualizza questo messaggio
   -H hostname               Hostname per connettersi a

L'interprete stampa il risultato delle operazioni sulle stringhe nello stesso modo in cui vengono inserite in input: tra virgolette, con virgolette interne ed altri caratteri particolari protetti da barre oblique inverse (NdT: 'backslash'), per mostrare il loro esatto valore. La stringa viene racchiusa tra doppie virgolette se contiene un apice singolo e non virgolette doppie, altrimenti è racchiusa tra apici singoli. (L'istruzione print, descritta più avanti, può essere usata per scrivere stringhe senza virgolette o caratteri di escape).

Le stringhe possono essere concatenate (incollate assieme) tramite l'operatore + e ripetute tramite *:

>>> parola = 'Aiuto' + 'A'
>>> parola
'AiutoA'
>>> '<' + parola*5 + '>'
'<AiutoAAiutoAAiutoAAiutoAAiutoA>'

Due stringhe letterali consecutive vengono concatenate automaticamente; la prima riga dell'esempio precedente poteva anche essere scritta come "parola = 'Aiuto' 'A'"; questo funziona solo con due stringhe di testo, non con espressioni arbitrarie che comprendano stringhe:

>>> 'str' 'ing'                   #  <-  Questo è ok
'string'
>>> 'str'.strip() + 'ing'         #  <-  Questo è ok
'string'
>>> 'str'.strip() 'ing'           #  <-  Questo non è valido
  File "<stdin>", line 1, in ?
    'str'.strip() 'ing'
                      ^
SyntaxError: invalid syntax

Le stringhe possono essere indicizzate come in C, il primo carattere di una stringa ha indice 0. Non c'è alcun tipo associato al carattere di separazione; un carattere è semplicemente una stringa di lunghezza uno. Come in Icon, possono essere specificate sottostringhe con la notazione a fette (NdT: 'slice'): due indici separati dal carattere due punti.

>>> parola[4]
'o'
>>> parola[0:2]
'Ai'
>>> parola[2:4]
'ut'

Gli indici della fetta hanno utili comportamenti predefiniti. Il primo indice, se omesso, viene impostato al valore predefinito 0. Se viene tralasciato il secondo, viene impostato alla dimensione della stringa affettata.

>>> parola[:2]    # I primi due caratteri
'Ai'
>>> parola[2:]    # Tutti eccetto i primi due caratteri
'utoA'

A differenza di quanto avviene in C, le stringhe Python non possono essere modificate. Un'assegnazione effettuata su un indice di una stringa costituisce un errore:

>>> parola[0] = 'x'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: object doesn't support item assignment
>>> parola[:1] = 'Lavagna'
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
TypeError: object doesn't support slice assignment

Comunque, creare una nuova stringa combinando i contenuti è semplice ed efficiente:

>>> 'x' + parola[1:]
'xiutoA'
>>> 'Lavagna' + parola[5]
'LavagnaA'

Ecco un'utile variante delle operazioni di affettamento: s[:i] + s[i:] equivale a s.

>>> parola[:2] + parola[2:]
'AiutoA'
>>> parola[:3] + parola[3:]
'AiutoA'

Gli indici di fetta degeneri vengono gestiti con eleganza: un indice troppo grande viene rimpiazzato con la dimensione della stringa, un indice destro minore di quello sinistro fa sì che venga restituita una stringa vuota.

>>> parola[1:100]
'iutoA'
>>> parola[10:]
''
>>> parola[2:1]
''

Gli indici possono essere numeri negativi, per iniziare il conteggio da destra. Ad esempio:

>>> parola[-1]     # L'ultimo carattere
'A'
>>> parola[-2]     # Il penultimo carattere
'o'
>>> parola[-2:]    # Gli ultimi due caratteri
'oA'
>>> parola[:-2]    # Tutta la stringa eccetto i due ultimi caratteri
'Aiut'

Si noti però che -0 è la stessa cosa di 0, quindi non si conta dall'estremità destra!

>>> parola[-0]     # (dato che -0 è la stessa cosa di 0)
'A'

Gli indici di fetta negativi vengono troncati se sono fuori intervallo, ma non si tenti di farlo con indici a singolo elemento:

>>> parola[-100:]
'AiutoA'
>>> parola[-10]    # errore
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
IndexError: string index out of range

Il modo migliore di tenere a mente come lavorano le fette è di pensare che gli indici puntano tra i caratteri, con l'indice 0 posto al margine sinistro del primo carattere. Quindi il margine destro dell'ultimo carattere di una stringa di n caratteri ha indice n, per esempio:

 +---+---+---+---+---+---+
 | A | i | u | t | o | A |
 +---+---+---+---+---+---+ 
 0   1   2   3   4   5   6
-6  -5  -4  -3  -2  -1

La prima riga di numeri dà la posizione degli indici 0...5 nella stringa; la seconda fornisce i corrispondenti indici negativi. La fetta da i a j consiste di tutti i caratteri compresi tra i margini contrassegnati i e j, rispettivamente.

Per indici non negativi, l'ampiezza di una fetta è pari alla differenza tra gli indici, se entrambi sono compresi nei limiti, per esempio la lunghezza di parola[1:3] è 2.

La funzione built-in len() restituisce la lunghezza di una stringa:

>>> s = 'supercalifragicospiristicalidoso'
>>> len(s)
32

Vedete anche:

Tipi sequenza
Le stringhe e le stringhe Unicode vengono descritte nella prossima sezione, vi sono esempi di tipi sequenza e supporto per comuni operazioni consentite su simili tipi.
Metodi stringa
Sia le semplici stringhe che quelle Unicode garantiscono un grande numero di metodi per le trasformazioni e ricerche di base.
Operazioni sulla formattazione delle stringhe
Le operazioni di formattazione vengono invocate quando le stringhe, semplici o Unicode, hanno alla loro sinistra l'operatore % descritto qui in dettaglio.


3.1.3 Stringhe Unicode

A partire da Python 2.0 il programmatore ha a sua disposizione un nuovo tipo di dato testo: l'oggetto Unicode. Può essere utilizzato per immagazzinare e manipolare dati Unicode (si veda http://www.unicode.org/ [off-site link] ) e si integra al meglio con gli oggetti stringa esistenti, garantendo conversioni in automatico ove necessario.

Unicode ha il vantaggio di fornire un unico ordinale per ogni carattere che possa comparire in un qualsiasi testo. In precedenza c'erano solo 256 ordinali possibili per i caratteri scrivibili e ciascun testo era tipicamente collegato a una pagina di codici che mappava gli ordinali sui caratteri scrivibili. Ciò provocava molta confusione specialmente riguardo al problema dell'internazionalizzazione del software (di solito indicata come "i18n" - "i" + 18 caratteri + "n"). Unicode ha risolto tali problemi definendo un'unica pagina di codici per tutti gli script.

Creare stringhe Unicode in Python è semplice quanto creare stringhe normali:

>>> u'Ciao mondo !'
u'Ciao mondo !'

Il carattere "u" minuscolo davanti agli apici indica che si vuole creare una stringa Unicode. Se si desidera includere nella stringa caratteri speciali, lo si può fare usando la codifica Python Unicode-Escape. Il seguente esempio mostra come fare:

>>> u'Ciao\u0020mondo !'
u'Ciao mondo !'

La sequenza di escape \u0020 inserisce il carattere Unicode con ordinale esadecimale 0x0020 (il carattere di spazio) nella posizione indicata.

Gli altri caratteri vengono interpretati usando il valore del loro rispettivo ordinale direttamente come Unicode. Grazie al fatto che i primi 256 caratteri Unicode sono gli stessi della codifica standard Latin-1 usata in molti paesi occidentali, l'inserimento Unicode risulta molto semplificato.

Per gli esperti, c'è anche una modalità raw, proprio come per le stringhe normali. Si deve prefissare una 'ur' minuscola alla stringa per far sì che Python usi la codifica Raw-Unicode-Escape. Non farà altro che applicare la conversione \uXXXX di cui sopra nel caso ci sia un numero dispari di barre oblique inverse davanti alla 'u' minuscola.

>>> ur'Ciao\u0020mondo !'
u'Ciao mondo !'
>>> ur'Ciao\\u0020mondo !'
u'Ciao\\\\u0020mondo !'

La modalità raw è utile perlopiù quando si devono introdurre un sacco di barre oblique inverse, p.e. nelle espressioni regolari.

A parte queste codifiche standard, Python fornisce un insieme completo di strumenti per creare stringhe Unicode partendo da una codifica conosciuta.

La funzione built-in unicode()permette l'accesso a tutti i codec (COdificatori e DECodificatori) Unicode ufficiali. Alcune delle codifiche più note nelle quali tali codec possono effettuare la conversione sono: Latin-1, ASCII, UTF-8 e UTF-16. Le ultime due sono codifiche a lunghezza variabile che permettono di memorizzare caratteri Unicode in uno o più byte. La codifica predefinita è normalmente impostata ad ASCII, che permette tutti i caratteri nell'intervallo da 0 a 127 e scarta tutti gli altri emettendo un errore. Quando si stampa una stringa Unicode, scrivendola in un file o convertendola con str(), viene usata la codifica predefinita.

>>> u"abc"
u'abc'
>>> str(u"abc")
'abc'
>>> u"äöü"
u'\xe4\xf6\xfc'
>>> str(u"äöü")
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2:
ordinal not in range(128)

Per convertire una stringa Unicode in una 8-bit si usa una specifica codifica, gli oggetti Unicode forniscono il metodo encode() che prende un argomento, il nome della codifica. Per le codifiche sono preferiti i nomi in minuscolo.

>>> u"äöü".encode('utf-8')
'\xc3\xa4\xc3\xb6\xc3\xbc'

Se si hanno dei dati in una codifica specifica e si vuole produrre una stringa Unicode corrispondente, si può usare la funzione unicode(), con il nome della codifica come secondo argomento.

>>> unicode('\xc3\xa4\xc3\xb6\xc3\xbc', 'utf-8')
u'\xe4\xf6\xfc'


3.1.4 Liste

Python riconosce una certa quantità di tipi di dati composti, usati per raggruppare insieme altri valori. Il più versatile è il tipo lista, che può essere scritto come una lista, compresa tra parentesi quadre, di valori (gli elementi della lista) separati da virgole. Gli elementi della lista non devono essere necessariamente tutti dello stesso tipo.

>>> a = ['spam', 'eggs', 100, 1234]
>>> a
['spam', 'eggs', 100, 1234]

Come per gli indici delle stringhe, gli indici delle liste iniziano da 0, e anche le liste possono essere affettate, concatenate e così via:

>>> a[0]
'spam'
>>> a[3]
1234
>>> a[-2]
100
>>> a[1:-1]
['eggs', 100]
>>> a[:2] + ['bacon', 2*2]
['spam', 'eggs', 'bacon', 4]
>>> 3*a[:3] + ['Boe!']
['spam', 'eggs', 100, 'spam', 'eggs', 100, 'spam', 'eggs', 100, 'Boe!']

Al contrario delle stringhe, che sono immutabili, è possibile modificare gli elementi individuali di una lista:

>>> a
['spam', 'eggs', 100, 1234]
>>> a[2] = a[2] + 23
>>> a
['spam', 'eggs', 123, 1234]

È anche possibile assegnare valori alle fette, e questo può pure modificare le dimensioni della lista:

>>> # Rimpiazza alcuni elementi:
... a[0:2] = [1, 12]
>>> a
[1, 12, 123, 1234]
>>> # Rimuove alcuni elementi:
... a[0:2] = []
>>> a
[123, 1234]
>>> # Inserisce alcuni elementi:
... a[1:1] = ['bletch', 'xyzzy']
>>> a
[123, 'bletch', 'xyzzy', 1234]
>>> a[:0] = a     # Inserisce (una copia di) se stesso all'inizio
>>> a
[123, 'bletch', 'xyzzy', 1234, 123, 'bletch', 'xyzzy', 1234]

La funzione built-in len() si applica anche alle liste:

>>> len(a)
8

È possibile avere delle liste annidate (contenenti cioè altre liste), ad esempio:

>>> q = [2, 3]
>>> p = [1, q, 4]
>>> len(p)
3
>>> p[1]
[2, 3]
>>> p[1][0]
2
>>> p[1].append('xtra')     # Si veda la sezione 5.1
>>> p
[1, [2, 3, 'xtra'], 4]
>>> q
[2, 3, 'xtra']

Si noti che nell'ultimo esempio, p[1] e q si riferiscono proprio allo stesso oggetto! Ritorneremo più avanti sulla semantica degli oggetti.


3.2 Primi passi verso la programmazione

Di certo possiamo usare Python per compiti più complessi che fare due più due. Per esempio, possiamo scrivere una sottosuccessione iniziale della serie di Fibonacci facendo come segue:

>>> # La serie di Fibonacci:
... # la somma di due elementi definisce l'elemento successivo
... a, b = 0, 1
>>> while b < 10:
...       print b
...       a, b = b, a+b
... 
1
1
2
3
5
8

Questo esempio introduce parecchie nuove funzionalità.

Vedete Circa questo documento... per informazioni su modifiche e suggerimenti.