- presentazione del sito
- Registrazione
- Eventi, mostre, convegni ed iniziative segnalate dalle aziende
- Recensioni ed articoli
- Le Mailing Lists
- La rivista Pc Ciechi
- Wiki
- Chi siamo
- Donazioni
- Un progetto degno di nota: Wintalbra
- Come navigare in questo sito
- rss
- Bancomat Accessibili sul territorio nazionale
- Contattaci
- I sostenitori di SpazioAusili
PYTHON: NOZIONI SULLA SINTASSI, SECONDA PARTE
FONTE: donato taddei su nvda, 15\04\2008, h. 21.24.
Nel precedente messaggio ci siamo fatti una idea di come python organizza i suoi dati, delle regole grammaticali che utilizza ecc.
Rinviamo a quando ne sapremo un po di più la lettura dei successivi capitoli del manuale da cui ho tratto il materiale postato:
in seguito ci sarà utile per completare il quadro sul funzionamento di questo linguaggio;
allo stato rischierebbe solo di far sembrare le cose più ostiche e complicate di quello che sono.
Ed ora, un po' di pubblicità
:Allora, analogamente a quanto faremmo nell'apprendere l'inglese o l'urdu, dopo aver introdotto le regole di scrittura e di pronuncia, passiamo al verbo
essere, alle prime frasi.
Insomma parliamo di istruzioni, che sono gli ingredienti base di gni linguaggio di programmazione allo stesso modo come le proposizioni sono le unità logiche
di base di un linguaggio parlato.
Va fatta subito unapremessa:
quando si dice che il python, java, perl, visualbasic ecc sono linguaggi di alto livello uno può pensare che quelli che usano il c, il delphi, o peggio
l'assembly sono degli sfigati.
Giusto l'opposto.
Un linguaggio di alto livello permette quasi a qualsiasi sfigato di pasticciare qualcosa senza nemmeno sapere chi l'ha creato,
proprio perchè l'alto livello sta nel linguaggio prima che i chi lo usa.
Da ciò consegue che se qualsiasi sfigato può pasticciare qualcosa, quelli dal manico buono fanno cose mostruose con pochissimo sforzo.
Un esempio è appunto il nostro nvda, pasticciato praticamente da una sola persona in un annetto.
Al contrario jaws era codificato in un linguaggio di medio livello, e perciò il suo sviluppo ha richiesto parecchi anni e di una equippe di sviluppatori.
Per lo stesso motivo fino a qualche anno fa i tifloesperti ritenevano casa quasi impossibile fare uno screen-reader.
I linguaggi di alto livello hanno poche istruzioni ma potenti e con quelle si fa tutto.
Una volta le case si facevano con cemento, sabbia, mattoni, ecc., oggi i palazzi si tirano su in qualche mese:
si tratta solo di assemblae pannellli, strutture prefabbricate, e quasi tutto il lavoro duro è assolto da macchine.
Dopo questa lunga premessa sarà chiaro perchè le istruzioni python che vado a presentare sono piuttosto poche, da poter stare in un messaggio di posta.
Nella prima parte infatti verranno presentati una dozzina abbondante di istruzioni cosiddette semplici, che cioè fanno una unica cosa.
Pensate a quanto sia scarno un dizionario di soli 15 verbi.
Ma al serpe basta o quasi perchè è di livello veramente alto.
Nella seconda parte di questo messaggio si entra precisamente nel vivo della programmazione
passando ad analizzare le 3 o 4 strutture logiche che permettono di far fare qualsiasi cosa ad un computer.
Poichè spesso si manifesta curiosità rispetto a questi argomenti e poichè di solito tale curiosità svanirebbe quasi sicuramente prima della fine di questo
messaggio,
(per noia ovviamente!), a beneficio di quelli cui vengono ogni tanto voglie generiche di saperne di programmazione,
partiamo a volo d'angelo da Adamo ed eva.
Le macchine hanno per sorte quella di liberare l'uomo da lavori ripetitivi.
Il computer soprattutto.
Come macchina non ha cervello. è stupido. Sa fare velocissimissimamente pochissime cose:
somme, confronti tra sequenze di bit, e pochissimo altro.
Perciò sono stati creati linguaggi artificiali che, utilizzando le pochissime cose che la macchina capisce, hanno costruito con esse delle funzionalità
via via più complesse che opportunamente codificate permettono alle macchine di fare le meraviglie che fanno.
La macchina dicevamo è per definizione un automa, capace al massimo di ripetere.
La forma più semplice è:
ripetere sempre la stessa cosa;
forma leggermente più complessa:
ripetere sempre le stesse cose nello stesso ordine, la stessa sequenza di cose:
così barsi la barba implica sempre prima insaponarsi poi radersi e poi lavarsi.
Questa è una sequenza di operazioni che nel testo di sotto hanno lasciato intradotto come suite.
La potremmo definire come una linea che collega da cima a fondo la sequenza, che inizi in cima e finisca al fondo.
Siamo in presenza di un flusso lineare, una sequenza appunto.
In caso di problemi il flusso viene interrotto saltando direttamente alla fine, ma sarà possibile
capire quasi immediatamente dove il filo si è interrotto.
Questo è il collegamento in serie degli elettrauto.
Questa è una delle strutture logiche fondamentali, la madre, di tutti i linguaggi di programmazione.
Sequenzqa codizionata
eseguire delle operazioni se ricorrono o non ricorrono determinate condizioni
portare l'ombrello se piove o minaccia di piovere
viceversa no
se il tabaccaio è aperto
prendi questo, quest'altro e ancora quest'altro
altrimenti
vai dal salumiere
se è aperto prendi questo e quest'altro
altrimenti bussa e fatti aprire
L'interruttore di una lampadina è un altro esempio.
e siamo a due strutture logiche fondamentali.
Normalmente viene detta alternativa, ma in alti tempi proprio per analogia con gli interruttori eletrici, fu detta anche deviatore.
può avere due differenti sequenze di operazioni:
in ogni caso la prima sarà eseguita solo se si verifica la condizione espressa
in forma ipotetica dove la condizione può anche essere il risultato di una serie di altre condizioni:
se (piove o mimaccia d piovere o (è sera e la tv prevede temporali in serata)
porto l'ombrello
In python questo va indentato perchè dipende logicamente dalla condizione
ma puà contenere anche un'altra sequenza di istruzioni da eseguirsi solo se la condizione posta non si verifica
se sei studo di leggere
tato canc (indentato)
else (altrimenti, allo stesso livello di indentazione dell'if)
beccati questo, quest'altro e tutto il papiello (ovviemente indentato rispetto all'else)
In un processo automatico la cosa più normale è la necessità di esguire sequenze di operazioni
per un determinato numero di situazioni:
il confezionamento di una partita di 2000 mutande implica per ciascuno di essi in sequenza la stiratura, la stampigliatura l'imbustamento.
la sequenza di queste tre operazioni dovà essere fatta per 2000 volte.
siamo a tre.
In questo caso si parla di cicli:
le operazioni vengono eseguite in sequenza ma arrivati alla fine si ricomincia daccapo come in un movimento circolare detto in gergo "loop" che potrebbe
anche essere infinito se non si prevedono condizioni per interromperlo.
C'è una variante di questo ciclo:
Una sequenza di operazioni deve essere svolta ogni volta che qualcuno ne faccia richiesta,
ovvero al verificarsi o meno di una data condizione
come il barista che indipendentemente dal numero dei clienti, ogni volta che ordinano un caffè compie la sequenza di operazioni relative:
caricare la macchina, sciacquare e riscaldare la tazza, servire e caso mai zuccherare.
Se a questo aggiungiamo un'ultima modalità, quella cioè di poter eseguire una data sequenza da un certo punto in poi,
come col programmatore di una lavatrice, siamo in grado di ridurre in programma quaslsiasi problema o processo.
Ovviamente tradurre i nostri desideri in ordine per il computer implica la mediazione d un qualche linguaggio, nè più nè meno che farsi capire da un gorilla,
da un pitone o da un umano.
.Ogni linguaggio avrà la sua pronuncia, la sua grammatica, la sua sintassi il suo vocabolario.
Non per questo cambia la sostanza, l'idea, il concetto di ciò che intendo fare.
Tornando a noi nella secondaparte del messaggio è appunto detto come si fa in python questo cui abbiamo alluso.
Queste vengono definite istruzioni composte perchè condizionano di solito una serie di istruzioni che da esse logicamente dipendono,
e sono solitamente dette in tutte le lingue istruzione per il contollo del flusso.
Infine l'ultima banalità:
in una azienda ogni dipendente svolge un certo compito, una certa funzione: l'addetto alle pulizie, il direttore, il magazziniere, il contabile, lo scaricatore,la
segretaria.
Ovviamente ciascuna funzione assolve a un compito specifico : prende ordine da qualcuno e risponde a qualcun altro.
Idem in un programma: ogni funzione assolve a un compito che si esplica attraverso sequenze più o meno condizionate e ripetitive di operazioni,
, ha un nom, viene chiamata in ballo da qualche altra di livello più alto e ad essa risponde.
Tornando alla nostra azienda: è vero che ognuno ha una propria funzione, ma non tutte sono uguali.
Così ci sono funzioni dirigenziali, di concetto, esecutive.
Così si appartiene alla classe operaia o a quella impiegatizia, alla razza padrona.
Ciascuna classe ha dei suoi parametri di valutazione (es. il titolo di studio), Ha dei vincoli funzionali (es. il portantino non può fare le siringhe e
l'infermiere operare),
ha un suo ambito specifico cui sono soggetti tutti i funzionari appartenenti a quella classe.
E quindi il cerchio si chiude dopo le alternative, i cicli con le definizioni di funzioni e di classi.
Conclusione: sono balle, è pigrizia, quando i nostri tiflosmanettoni che sanno sempre tutto di ogni jawso,
dicono di non essere programmatori con un mix acidoso di schifo, sufficienza e ammirazione, e peggio i prof. che raccontano che loro sono autisti non meccanici
quasi che un autista non debba sapere che mestiere fa l'olio nel motore.
Donato Taddei
Manuela di riferimento del Python:
Capitolo 6
6. Istruzioni semplici
Le istruzioni semplici sono comprese all'interno di una singola riga
logica.
Alcune istruzioni semplici possono trovarsi su di una singola
riga, separate da punti e virgola.
6.1 Espressioni di istruzioni
Le espressioni di istruzioni vengono usate (prevalentemente in modo
interattivo) per calcolare e scrivere un valore, o (di solito) per
chiamare una procedura (una funzione che restituisce un risultato
significativo; in Python, le procedure restituiscono il valore None).
Un'espressione di istruzioni valuta la lista delle espressioni (che
può essere una singola espressione).
6.2 Istruzioni assert
Le istruzioni sono un modo utile per inserire asserzioni di controllo
nel programma:
La forma semplice, "assert espressione", è equivalente a
if __debug__:
if not expression: raise AssertionError
Come dice la parola asserisce che una o più condizioni siano vere o false.
Serve, nel debug, per simulare il verificarsi delle condizioni che si vogliono testare.
6.3 Istruzioni di assegnamento
Le istruzioni di assegnamento vengono usate per (ri)legare nomi a
valori e modificare attributi o elementi di oggetti mutabili:
Un'istruzione di assegnamento valuta la lista delle espressioni
(ricordando che questa può essere una singola espressione o una lista
separata da virgole, l'ultima produce una tupla) e assegna ogni
singolo oggetto risultante ad ognuno dei riferimenti forniti, da
sinistra a destra.
AVVERTENZE: benché la definizione di assegnamento implichi che
sovrapposizioni tra la parte sinistra e destra siano `innocue' (per
esempio, "a, b = b, a" scambia le due variabili), sovrapposizioni
all'interno della collezione di variabili assegnate non sono sicure!
Per esempio, il seguente programma visualizza "[0, 2]":
x = [0, 1]
i = 0
i, x[i] = 1, 2
print x
6.3.1 Dichiarazioni di assegnamento incrementale
L'assegnamento incrementale è la combinazione, in una singola
istruzione, di un'operazione binaria e un'istruzione di assegnamento:
ultimi tre assegnamenti.)
Un assegnamento incrementale valuta l'obiettivo (che, a differenza
delle normali istruzioni di assegnamento, non può essere un parametro
unpacking) e l'espressione, esegue l'operazione binaria specifica per
il tipo di operazione dei due operandi e assegna il risultato
all'obiettivo originale. L'obiettivo viene valutato una sola volta.
Un'espressione di assegnamento incrementale come x += 1 può essere
riscritto come x = x + 1 per ottenere la stessa cosa, ma non
esattamente lo stesso effetto. Nella versione incrementale, x viene
valutata solamente una volta. Inoltre, quando possibile, l'operazione
viene eseguita sul posto, il che significa che invece di creare un
nuovo oggetto e assegnarlo all'obiettivo, viene modificato il vecchio
oggetto.
Con l'eccezione dell'assegnamento di tuple ed obiettivi multipli in
una singola dichiarazione, l'assegnamento fatto attraverso una
dichiarazione incrementale viene gestito nello stesso modo di un
normale assegnamento. In modo simile, con l'eccezione del possibile
comportamento sul posto, l'operazione binaria viene eseguita nello
stesso modo di una normale operazione binaria.
Per obiettivi che sono riferimenti ad attributi, il valore iniziale
viene ottenuto con getattr() ed il risultato viene assegnato con
setattr(). Da notare che i due metodi non si riferiscono
necessariamente alla stessa variabile. Quando getattr() fa riferimento
ad una variabile di classe, setattr() si riferisce ancora ad una
variabile istanza. Per esempio:
class A:
x = 3 # variabile di classe
a = A()
a.x += 1 # scrive a.x come 4 lasciando A.x come 3
6.4 L'istruzione pass
pass è un'operazione nulla -- quando viene eseguita, non succede
niente. Diviene utile quando viene richiesta sintatticamente
un'istruzione ma non è necessario nessun codice per l'esecuzione, per
esempio:
def f(arg): pass # una funzione che non fa (ancora) niente
class C: pass # una classe senza metodi (ancora)
6.5 L'istruzione del
La cancellazione viene definita ricorsivamente nello stesso modo in
cui viene definito l'assegnamento. Invece di descriverla in dettaglio,
si daranno alcuni accenni.
La cancellazione di una lista rimuove ricorsivamente ogni elemento, da
sinistra a destra.
La cancellazione di un nome rimuove i suoi legami dallo spazio dei
nomi locale o globale, a seconda se il nome si trova in un'istruzione
global nello stesso blocco di codice. Se il nome non ha legami, verrà
sollevata un'eccezione NameError.
Non è legale cancellare un nome dallo spazio dei nomi locale se
succede ad una variabile vuota in un blocco annidato.
La cancellazione di riferimenti ad attributo, subscription e
affettazioni viene passata all'oggetto primario coinvolto; la
cancellazione di un'affettazione è in generale equivalente
all'assegnamento di una fetta vuota del tipo giusto (ma anche questo
viene determinato dall'oggetto affettato).
6.6 L'istruzione print
print valuta un'espressione alla volta e scrive l'oggetto risultante
sullo standard output (vedere sotto). Se un oggetto non è una stringa,
viene prima convertito in una stringa usando le regole per la
conversione. La stringa (risultante o originale) viene quindi scritta.
Prima di ogni oggetto viene scritto uno spazio a meno che il sistema
di output non creda che sia posizionato all'inizio di una riga. Questo
è il caso (1) quando nessun carattere è stato ancora scritto sullo
standard output, (2) quando l'ultimo carattere scritto sullo standard
output è "\n", o (3) quando l'ultima operazione di scrittura sullo
standard output non è stata un'istruzione print. (Per questa ragione
in alcuni casi può essere funzionale scrivere una stringa vuota sullo
standard output.) Note: gli oggetti che si comportano come oggetti
file ma che non sono oggetti file built-in, spesso non emulano
appropriatamente questo aspetto del comportamento degli oggetti file,
così non è buona norma fare affidamento su questo comportamento.
Nota:
A cecolandia standard output è sinomimo di prompt dei comandi.
Più precisamente tutte le applicazioni console, che utilizzano cioè per linput e l'output lo standard ansi, tra cui anche il prompt dei comandi
ricevono dal sistema operativo questi tre buffe per l'input, l'output e i messaggi di errore.
Per iciso il prompt dei comandi associa lo stesso indirizzo a questi due buffer per cui, a differenza che sui sistemi unix, i messaggi di errore compaiono
mescolati all'output e non jè possibile separarli.
Lo standard output viene definito come l'oggetto file chiamato stdout
nel modulo built-in sys. Se non esiste nessun oggetto, o se non
possiede un metodo write(), viene sollevata un'eccezione RuntimeError.
return può solo apparire sintatticamente all'interno di una
definizione di funzione, non all'interno di una definizione di classe.
Se è presente una lista di espressioni questa viene valutata,
altrimenti viene restituito None.
return abbandona la chiamata alla funzione corrente, con la lista di
espressioni (o None) come valore restituito.
Quando return passa il controllo oltre una istruzione try con una
clausola finally, la clausola finally viene eseguita prima di lasciare
realmente la funzione.
6.8 L'istruzione yield
L'istruzione yield viene usata solo quando si definisce una funzione
generatore e viene usata solo nel corpo della funzione generatore.
L'uso dell'istruzione yield nella definizione di una funzione è
sufficiente a creare una funzione generatore invece che una normale
funzione.
Quando viene chiamata, una funzione generatore restituisce un
iteratore conosciuto come un generatore iteratore, o più comunemente,
un generatore. Il corpo della funzione generatore viene eseguito da
una chiamata reiterata al metodo next() del generatore fino al
sollevamento di un'eccezione.
Nota:
per funzione generatore deve intendersi una funzione che, una volta chiamata, viene eseguita ricorsivamente potendo accettare parametri diversi ad ogni
esecuzione.
a ciascuna viene
Quando viene eseguita l'istruzione yield, lo stato del generatore
viene congelato ed il valore dell'expression_list viene restituita
alla chiamata next(). Per ``congelata'' si intende che tutto lo stato
locale viene conservato, inclusi i legami correnti delle variabili
locali, il puntatore all'istruzione e lo stack di valutazione interno:
sono salvate sufficienti informazioni, cosicché la prossima volta che
viene invocato next(), la funzione possa procedere esattamente come se
l'istruzione yield fosse una chiamata dall'esterno.
6.9 L'istruzione raise
Se non sono presenti espressioni, raise risolleva l'ultima espressione
che era stata attivata nel corrente ambito di visibilità. Se nessuna
eccezione è attiva nel corrente ambito di visibilità, viene sollevata
un'eccezione che indica questo errore.
risollevare nuovamente un'eccezione in modo trasparente in una
clausola except, ma raise senza espressioni dovrebbe essere preferito
Nota:
quando una persona non vuole o non pò fare una certa cosa si dice che comincia a sollevare eccezioni.
Quando al pitone non sta bene qualcosa solleva eccezioni, in pratica si rifiuta di proseguire e ti sibila pure il motivo.
Poicè è un animale docile gli si può anche dire:
dai su prova a farlo lo stesso,
e se il padrone si incazza mettigliela così.
per questo c'è l'istruzione "try" (prova)
e la clausola except che appunto sta a dire:
poichè ci sono problemi, fai in quest'altro modo.
Quando si devono far fare cose complicate per cui possono sorgere problemi di ogni tipo e prima di trovarsi qualche rebus,
uno può dire:
ad ogni passo che faccio vado prima a domandare se ci sono problemi.
Così me li affronto uno alla volta.
Allora dico al serpe:
ueh! alzati, raise. Visto che a te non te ne sta mai bene una dimmi in queta cosa che c'è che non va.
6.10 L'istruzione break
break può trovarsi sintatticamente annidato in un ciclo for o while,
ma non annidato in una funzione o definizione di classe senza uno di
quei due cicli.
Termina il ciclo più vicino, saltando la clausola facoltativa else se
il ciclo ne ha una.
Se un ciclo for finisce con un break, l'obiettivo del controllo del
ciclo acquisisce il suo valore corrente.
Quando break passa il controllo fuori dall'istruzione try con una
clausola finale, questa clausola finally viene eseguita prima che sia
abbandonato realmente il ciclo.
Nota:
break interrompe azioni ripetitive appunto uscendo da quel ciclo.
6.11 L'istruzione continue
continue può solo trovarsi sintatticamente annidato in un ciclo for o
while, ma non annidato in una funzione o in una definizione di classe
o in un'istruzione try all'interno di quel ciclo.^6.1 Prosegue con il
ciclo sussessivo.
6.12 L'istruzione import
Le istruzioni import vengono eseguite in due passi: (
1) cercare un modulo, ed inizializzarlo se necessario; (
2) definire un nome o nomi nello spazio dei nomi locale (nel medesimo ambito di visibilità in cui
viene eseguita l'istruzione import).
La prima forma (senza from) ripete questi passi per ogni identificatore nella lista.
La forma con from) svolge il passo (1) una volta e quindi svolge ripetutamente il
passo 2.
In questo contesto, per ``inizializzare'' una built-in, un modulo
estensione significa chiamare una funzione di inizializzazione che
deve essere fornita dal modulo per l'uso (nelle implementazioni di
riferimento, il nome della funzione è ottenuto antecedendo la stringa
``init'' al nome del modulo);
Il sistema mantiene una tavola dei moduli che sono stati o saranno
inizializzati, indicizzandoli per nome. Questa tavola è accessibile
come sys.modules. Quando il nome di un modulo viene trovato in questa
tavola, il passo (1) è finito. Altrimenti, inizia la ricerca per la
definizione di un modulo. Quando un modulo è stato trovato, viene
caricato.
Se viene trovato un modulo built-in, il suo codice di inizializzazione
built-in viene eseguito ed il passo (1) è terminato. Se non ci sono
file che hanno corrispondenze, viene sollevata un'eccezione
ImportError. Se viene trovato un file, viene analizzato, restituendo
un blocco di codice eseguibile. Se avviene un errore di sintassi,
viene sollevata un'eccezione SyntaxError. Altrimenti, viene creato un
modulo vuoto con un dato nome ed inserito nella tavola dei moduli, e
quindi viene eseguito il blocco di codice nel contesto di questo
modulo. Eccezioni durante questa esecuzione terminano il passo (1).
Quando il passo (1) finisce senza avere sollevato eccezioni, il passo
(2) può iniziare.
La prima forma dell'istruzione import collega il nome del modulo nello
spazio dei nomi locale all'oggetto modulo, e quindi va ad importare il
prossimo identificatore, se c'è nè qualcuno. Se il nome del modulo
viene seguito da as, il nome successivo ad as viene usato come spazio
dei nomi locale per il modulo.
La forma from non collega il nome del modulo: attraversa la lista
degli identificatori, guarda in ognuno di loro con riguardo al modulo
trovato al passo (1) e collega il nome allo spazio dei nomi locale
all'oggetto così trovato. Come con la prima forma di import, un nome
locale alternativo può essere fornito specificndo "as nome locale". Se
un nome non viene riscontrato, viene sollevata un'eccezione
ImportError. Se la lista degli identificatori viene sostituita da una
stella ("*"), tutti i nomi pubblici definiti nel modulo vengono legati
allo spazio dei nomi locale dell'istruzione import.
I nomi pubblici definiti da un modulo vengono determinati dalla
ricerca nello spazio dei nomi dei moduli per una variabile chiamata
__all__; se definita, deve essere una sequenza di stringhe che
rappresentano nomi definiti o importati da quel modulo. I nomi dati in
__all__ vengono considerati pubblici e sono necessari perché esistano.
Se __all__ non viene definito, la gamma dei nomi pubblici include
tutti i nomi trovati nello spazio dei nomi del modulo che non iniziano
con un carattere di sottolineatura ("_"). __all__ dovrebbe contenere
l'intera API pubblica. Questo viene inteso per evitare l'esportazione
accidentale di elementi che non sono parte dell'API (come moduli della
libreria che erano stati importati e usati senza il modulo).
Nomi dei moduli gerarchici: quando il nome dei moduli contiene uno o
più punti, il percorso di ricerca del modulo viene effettuato
differentemente. La sequenza di identificatori sopra l'ultimo punto
viene usata per trovare un ``package''; l'identificatore finale viene
quindi cercato all'interno del package. Un package è generalmente una
sottodirectory di una directory su sys.path che ha un file
__init__.py..
6.12.1 Istruzioni future
Un'istruzione future è una direttiva per il compilatore per un modulo
particolare che dovrebbe essere compilato usando una sintassi o una
semantica che sarà disponibile in una versione futura di Python.
L'istruzione future è intesa per migrare facilmente ad una versione
futura di Python che introduce cambiamenti incompatibili per il
linguaggio. Permette l'uso delle nuove caratteristiche su una base di
propri moduli, prima che la release in cui si trova la caratteristica
diventi standard.
Un'istruzione future deve apparire vicino la parte alta del modulo.
6.13 L'istruzione global
L'istruzione global è un'istruzione che viene mantenuta per l'intero
blocco di codice corrente. Questo significa che gli identificatori
elencati verranno interpretati come globali. Dovrebbe essere
impossible assegnare una variabile globale senza global, sebbene le
variabili libere possano fare riferimento a globalità senza essere
state dichiarate global.
I nomi elencati in un'istruzione global non devono essere usati nello
stesso blocco di codice testuale che precede quell'istruzione global.
I nomi elencati nell'istruzione global non devono essere definiti come
parametri formali o in un ciclo for per il controllo dell'obiettivo,
in una definizione di classe (class), in una definizione di funzione,
o un'istruzione import.
6.14 L'istruzione exec
Questa istruzione supporta l'esecuzione dinamica di codice Python. La
prima espressione dovrebbe valutare se sia una stringa, un file
oggetto aperto o un oggetto codice. Se è una stringa, viene analizzata
come un insieme di istruzioni Python che quindi vanno eseguite (a meno
che non avvengano errori di esecuzione). Se è un file aperto, viene
analizzato prima della fine del file EOF ed eseguito. Se è un oggetto
codice viene semplicemente eseguito.
In tutti i casi, se le parti facoltative vengono omesse, il codice
viene eseguito nella forma corrente. Se viene specificata solo la
prima espressione dopo in, dovrebbe essere un dizionario, che verrà
usato sia per la variabili globali che per quelle locali. Se sono date
due espressioni, devono essere entrambe dizionari e saranno usati
rispettivamente per la variabili globali e locali.
Suggerimento per i programmatori: la valutazione dinamica delle
espressioni viene supportata dalla funzione built-in eval(). Le
funzioni built-in globals() e locals() restituiscono rispettivamente
il corrente dizionario globale e locale, che può essere utile per
passare valori nell'uso di exec.
7. Istruzioni composte
Le istruzioni composte contengono (gruppi di) altre istruzioni;
influenzano o controllano in qualche modo l'esecuzione di queste altre
istruzioni. In generale, le istruzioni composte durano per molte
righe, sebbene in semplici forme un'istruzione composta completa possa
essere contenuta in una sola riga.
Le istruzioni if, while e for implementano costrutti tradizionali di
controllo di flusso.
try except specifici gestori per eccezioni e/o codice più pulito per un gruppo di istruzioni.
Anche le funzioni e le definizioni di classe sono istruzioni composte.
Le dichiarazioni composte consistono in una o più 'clausole'.
Una clausola consiste di un'intestazione e di una 'suite'.
Le clausole d'intestazione di una particolare istruzione composta sono tutte allo
stesso livello di indentazione.
Ogni clausola d'intestazione inizia con una parola chiave identificabile univocamente e finisce con il
carattere due punti.
Una suite è un gruppo di istruzioni controllate da una clausola.
Una suite può essere composta da una o più semplici istruzioni poste sulla stessa riga dell'intestazione, separate da un carattere due punti, seguendo
i due punti dell'intestazione, o può
essere composta da una o più istruzioni indentate sulle righe susseguenti.
Solo l'ultima forma di composizione della suite può
contenere istruzioni composte;
Si noti anche che i due punti uniscono in modo più costrittivo che il
punto in questo contesto, così come quello nel seguente esempio, una,
tutte o nessuna delle istruzioni print stampate viene eseguita:
if x < y < z: print x; print y; print z
Si noti che l'istruzione finisce sempre con una NEWLINE seguita
possibilmente da una DEDENT .
La formattazione delle regole grammaticali nella seguente sezione
mette ogni clausola in una riga separata, per chiarezza.
7.1 L'istruzione if
L'istruzione if viene usata per esecuzioni condizionali:
Seleziona esattamente una delle suite per valutare l'espressione una
per una fino a che una non risulta vera (vedere la sezione 5.10 per la
definizione di vero e falso); quindi quella suite viene eseguita (e
nessun altra parte dell'istruzione if viene eseguita o valutata). Se
tutte le espressioni sono false, viene eseguita la suite della
clausola else, se presente.
7.2 L'istruzione while
L'istruzione while viene usata per esecuzioni ripetute fino a che
un'espressione non risulti vera:
Questo esegue ripetutamente l'epressione e, se risulta vera, esegue la
prima suite; se l'espressione risulta falsa (potrebbe essere la prima
volta che viene provata) la suite della clausola else, se presente,
viene eseguita ed il ciclo termina.
Un'istruzione break eseguita nella prima suite termina il ciclo senza
eseguire la clausola else della suite. Un'istruzione continue,
eseguita nella prima suite, salta il resto della suite e ritorna
indietro per eseguire nuovamente l'espressione.
Nota:
il costruitto while(condizione) appartiene praticamente a tutti i linguaggi di programmazione.
sia nella forma affermativa
ripeti finchè è vera questa condizione
e nella forma negativa
ripeti fin quando non si verifica questa condizione (until)
qui invece lo schema è:
ripeti while(condizione
ealtrimenti else fa quest'altro.
7.3 L'istruzione for
L'istruzione for viene usata per iterare attraverso gli elementi di
una sequenza (come una stringa, una tupla o una lista) o altri oggetti
iterabili:
L'espressione list viene valutata una volta; dovrebbe produrre una
sequenza. La suite viene quindi eseguita una volta per ogni elemento
nella sequenza, in ordine ascendente rispetto all'indice. Ogni
elemento viene assegnato a turno alla lista obiettivo, usando le
regole standard dell'assegnazione e quindi viene eseguita la suite.
Quando gli elementi sono esauriti (quando la sequenza è vuota questo
accade immediatamente), la suite nella clausola else, se presente,
viene eseguita ed il ciclo termina.
Un'istruzione break eseguita nella prima suite finisce il ciclo senza
eseguire le clausole else della suite. Un'istruzione continue eseguita
nella prima suite salta il resto della suite e continua con l'elemento
successivo, o con la clausola else se il prossimo elemento non esiste.
La suite può assegnare alla variabile (i) la lista obiettivo; questo
non influenzerà l'elemento successivo assegnato alla stessa suite.
La lista obiettivo non viene cancellata quando il ciclo è finito, ma
se la sequenza è vuota, non verrà assegnata a nessuna variabile per
tutto il ciclo. Suggerimento: la funzione built-in range() restituisce
una sequenza di interi utilizzabili per emulare l'effetto del Pascal
for i := a to b do; per esempio, range(3) restituisce la lista [0, 1,
2].
C'è una finezza quando la sequenza viene modificata dal ciclo (questo
può avvenire solamente per sequenze modificabili, per esempio nel caso
di liste). Un contatore interno viene usato per tenere traccia del
prossimo elemento usato e viene incrementato ad ogni iterazione.
Quando questo iteratore ha raggiunto la lunghezza della sequenza il
ciclo finisce. Questo significa che se la suite cancella l'elemento
corrente (o il precedente) dalla sequenza, il prossimo elemento verrà
saltato (fino a che non acquisisce l'indice dell'elemento corrente che
è stato già trattato). In modo simile, se la suite inserisce un
elemento nella sequenza prima dell'elemento corrente, l'elemento
corrente verrà trattato ancora la prossima volta attraverso il ciclo.
Questo può portare a bug fastidiosi che possono essere annullati
facendo una copia temporanea dell'intera sequenza,per esempio,
for x in a[:]:
if x < 0: a.remove(x)
7.4 L'istruzione try
L'istruzione try specifica i gestori delle eccezioni e/o le azioni di
pulizia del codice per un gruppo di istruzioni:
Ci sono due forme di istruzioni try: try...except e try...finally.
Queste forme non possono essere mischiate (ma possono essere annidate
in ogni altra).
La forma try...except specifica uno o più gestori di eccezioni (la
clausola except). Quando non avvengono eccezioni nella clausola try,
non viene eseguito nessun gestore di eccezioni. Quando viene sollevata
un'eccezione nella suite try, viene avviata la ricerca per un gestore
di eccezioni. Questa ricerca ispeziona le clausole except una ad una
finché non ne viene trovata una che verifica l'eccezione. Una clausola
per un'eccezione expression-less, se presente, deve essere l'ultima;
questa verifica ogni eccezione. Per una clausola except con
un'espressione, viene cercata quell'espressione e la clausola cerca
l'eccezione se il risultante oggetto è ``compatibile'' con
l'eccezione. Un oggetto è compatibile con un'eccezione se quest'ultima
è anche l'oggetto che identifica l'eccezione, o (per eccezioni che
sono anche classi) si intende una classe base di una eccezione, o è
una tupla contenente un elemento che è compatibile con l'eccezione.
Notare che l'identità dell'oggetto deve corrispondere, per esempio
deve essere lo stesso oggetto, non solamente un oggetto con lo stesso
valore.
Se nessuna clausola except corrisponde all'eccezione, la ricerca per
un gestore di eccezione continua nel codice vicino e sulla pila
invocata.
Prima che una clausola except della suite venga eseguita, i dettagli
dell'eccezione vengono assegnati alle tre variabili del modulo sys:
sys.exc_type riceve l'oggetto che identifica l'eccezione;
sys.exc_value riceve i parametri dell'eccezione; sys.exc_traceback
riceve un oggetto traceback (vedere la sezione 3.2) identificando nel
programma il punto dove è stata sollevata l'eccezione. Questi dettagli
sono anche disponibili attraverso la funzione sys.exc_info(), che
restituisce una tupla (exc_type, exc_value, exc_traceback). L'uso
delle variabili corrispondenti è deprecato in favore di questa
funzione, da quando il loro uso è insicuro in un programma che fa uso
dei thread. Come per Python 1.5, le variabili vengono riportate al
loro precedente valore (prima della chiamata) quando ritornano da una
funzione che ha gestito un'eccezione.
La clausola facoltativa else viene eseguita se e quando il controllo
di flusso va oltre la fine della clausola try.^7.1 Le eccezioni della
clausola else non vengono gestite dalle precedenti clausole except.
La forma try...finally specifica un gestore di pulizia. La clausola
try viene eseguita. Quando non vengono sollevate eccezioni, la
clausola finally viene eseguita. Quando viene sollevata un'eccezione
Quando un'istruzione return, break o continue viene eseguita nella
suite try di un'istruzione try...finally, viene eseguita anche la
clausola finally.
7.5 Definizioni di funzione
Una definizione di funzione definisce un oggetto funzione definito
dall'utente (vedere la sezione 3.2):
Una definizione di funzione è un'istruzione eseguibile. La sua
esecuzione collega il nome della funzione nello spazio dei nomi locale
corrente alla funzione oggetto (un wrapper attorno al codice
eseguibile per la funzione). Questa funzione oggetto contiene un
riferimento al corrente spazio dei nomi globale come lo spazio dei
nomi globale che deve essere usato quando viene chiamata la funzione.
La definizione della funzione non esegue il corpo della funzione;
questa viene eseguita solo quando viene chiamata la funzione.
Quando uno o più parametri di alto livello hanno la forma parameter =
expression, si dice che la funzione ha ``i valori dei parametri
predefiniti''. Per un parametro con un valore predefinito, l'argomento
corrispondente può essere omesso dalla chiamata, in quel caso il
parametro predefinito viene sostituito. Se il parametro ha un valore
predefinito, tutti i parametri che seguono devono avere anche loro un
valore predefinito --
I valori dei parametri predefiniti vengono valutati quando la
definizione di funzione viene eseguita. Questo significa che
l'espressione viene valutata una volta, quando la funzione viene
definita e quindi il solito valore ``pre-calcolato'' viene usato per
ogni chiamata. Questo è particolarmente importante per capire quando
un parametro predefinito è un oggetto mutabile, come una lista o un
dizionario: se la funzione modifica l'oggetto (per esempio aggiungendo
un elemento ad una lista), il valore predefinito viene in effetti
modificato. Questo è, generalmente, quello che intendevamo.
Un modo
per aggirare questo comportamento è usare None come valore predefinito
e provarlo esplicitamente nel corpo della funzione, per esempio:
def whats_on_the_telly(penguin=None):
if penguin is None:
penguin = []
penguin.append("property of the zoo")
return penguin
Le semantiche delle funzioni di chiamata vengono descritte in modo più
dettagliato nella sezione 5.3.4. Una funzione chiama sempre i valori
assegnati a tutti i parametri menzionati nella lista dei parametri,
insieme agli argomenti posizionali, dagli argomenti delle parole
chiave. Se è presente la forma ``*identifier'', viene inizializzata
come una tupla, ricevendo ogni parametro posizionale eccedente,
predefinita come una tupla vuota. Se invece è presente la forma
``**identifier'', viene inizializzata come un nuovo dizionario che
riceverà ogni argomento delle parole chiave in eccesso, predefinito
come un nuovo dizionario vuoto.
È anche possibile creare funzioni anonime (funzioni non legate ad un
nome), da usare immediatamente nelle espressioni. Queste usano le
forme lambda, descritte nella sezione 5.11. Notare che la forma lambda
è solo una scorciatoia per una definizione semplificata di una
funzione; una funzione definita in un'istruzione ``def'' può essere
fornita o assegnata ad un altro nome proprio come una funzione
definita nella forma lambda. La forma ``def'' è attualmente la più
potente da quando permette l'esecuzione di istruzioni multiple.
7.6 Definizioni di classe
Una definizione di classe definisce un oggetto classe (vedere la
sezione 3.2):
Una definizione di classe è un'istruzione eseguibile. Prima valuta la
lista ereditata, se presente. Ogni elemento nella lista ereditata
dovrebbe valutare un oggetto classe o una classe tipo che ne permetta
la derivazione. La suite delle classi viene quindi eseguita in una
nuova cornice di esecuzione (vedere la sezione 4.1), usando un nuovo
spazio dei nomi creato localmente e lo spazio dei nomi globale
originale. (
Di solito, la suite contiene solo le definizione delle
funzioni.) Quando la suite delle classi finisce l'esecuzione, la sua
cornice di esecuzione viene scaricata, ma viene salvato il suo spazio
dei nomi locale.
Una oggetto classe viene quindi creato usando la
lista ereditata per le classi base e lo spazio locale dei nomi viene
salvato per il dizionario degli attributi. Il nome della classe è
legato a questa classe oggetto nello spazio dei nomi originale.
Nota per i programmatori: Le variabili definite nelle definizioni di
classe sono variabili di classe; vengono condivise da tutte le
istanze. Per definire le variabili istanza, deve essere specificato un
valore nel metodo __init__() o in un altro metodo. Sia la classe che
la variabile istanza sono accessibili attraverso la notazione
``self.name'' ed una variabile istanza nasconde una variabile di
classe con lo stesso nome quando vi si accede in questo modo. Le
variabili di classe con valori immutabili possono essere usate come
predefinite per variabili istanza. Per le classi di nuovo stile, i
descrittori possono essere usati per creare variabili d'istanza con
differenti dettagli d'implementazione.
8. Componenti di alto livello
L'interprete Python può prendere il proprio input da svariate
sorgenti: da uno script passatogli come standard input o come
argomento di un programma, scritto interattivamente, dal sorgente di
un modulo, etc.. Questo capitolo mostra la sintassi usata in questi
casi.
8.1 Programmi completi in Python
Mentre le specifiche di un linguaggio non hanno la necessità di
prescrivere come l'interprete del linguaggio debba essere invocato, è
però utile avere una nozione di un programma Python completo. Un
programma Python completo viene eseguito in un ambiente inizializzato
in modo minimale: tutti i moduli built-in e standard sono disponibili,
ma non sono stati inizializzati, con l'eccezione di sys (vari servizi
di sistema), __builtin__ (funzioni built-in, eccezioni e None) e
__main__. L'ultimo viene usato per fornire lo spazio dei nomi locale e
globale per l'esecuzione del programma completo.
La sintassi per un programma Python completo è come quella per i file
in input, descritta nella prossima sezione.
L'interprete può essere invocato anche in modo interattivo; in questo
caso, non legge ed esegue un programma completo ma legge ed esegue
un'istruzione (possibilmente composta) alla volta. L'ambiente iniziale
è identico a quello del programma completo; ogni istruzione viene
eseguita nello spazio dei nomi di __main__.
Sotto Unix, un programma completo può essere passato all'interprete in
tre forme:
con l'opzione -c string da riga di comando, come un file
passato come primo argomento da riga di comando, o come standard
input. Se il file o lo standard input sono un dispositivo tty,
l'interprete entra nel modo interattivo; altrimenti esegue il file
come un programma completo.
8.2 File in input
Tutti gli input letti da un file non interattivo hanno la stessa
forma:
Questa sintassi viene usata nelle seguenti situazioni:
* quando analizza un programma Python completo (da un file o da una
stringa);
* quando analizza un modulo;
* quando analizza una stringa passata all'istruzione exec;
8.3 Input interattivo
Si noti che un'istruzione composta di alto livello può essere seguita
da una riga vuota in modalità interattiva; questo è necessario per
aiutare l'analizzatore a trovare la fine dell'input.