Moduli e pacchetti

Per facilitare la manutenzione e la lettura di programmi troppo lunghi, questi possono essere suddivisi in moduli, raggruppando gli elementi correlati. I moduli sono delle entità che permettono l’organizzazione e la divisione logica del nostro codice. I files sono la sua controparte fisica: ogni file Python memorizzato sul disco è equivalente a un modulo.
Moduli
Creiamo il nostro primo modulo salvando allora un piccolo file modulo.py con i seguenti contenuti:
			def mia_funzione():
			    print "una funzione"
			
			class MiaClasse:
			    def __init__(self):
			        print "una classe"
			
			print "un modulo"
Se vogliamo usare le funzionalità definite in questo modulo nel nostro programma si deve importare. Per importare un modulo si utilizza la parola chiave import seguita dal nome del modulo, che è il nome del file meno l’estensione. Come esempio, salviamo un file con il nome programma.py nella stessa directory dove avete salvato il file del modulo (questo è importante, perché se non è nella stessa directory, Python non riesce a trovarlo) con i seguenti contenuti:
			import modulo
			modulo.mia_funzione()
L’import non solo ci rende disponibili tutto ciò che è stato definito all’interno del modulo, ma esegue anche il codice del modulo. Per questo motivo il nostro programma, oltre a stampare il testo “una funzione” quando si chiama mia_funzione, stampa anche il testo “un modulo“, dovuto al print del modulo importato. Non stamperebbe invece il testo “una classe” perché ciò che è stato fatto nel modulo fù solo la definizione della classe e non la sua istanzazione.
La clausola import permette anche d’importare più moduli nella stessa linea. Nel seguente esempio vediamo come si importa in una singola clausola i moduli della distribuzione di default Python: os, che include le funzionalità relative al sistema operativo; sys, con le funzionalità relative all’interprete Python stesso e time in cui ci sono funzioni per manipolare le date e gli orari.
			import os, sys, time
			print time.asctime()
Senza dubbio avrete visto su questo e l’esempio precedente un dettaglio importante: è necessario far precedere il nome degli oggetti importati da un modulo con il nome del modulo a cui appartengono, o che è lo steso, con lo spazio dei nomi su cui si trovano. Questo permette di non sovrascrivere accidentalmente qualche altro oggetto che ha lo stesso nome al momento d’importare un altro modulo.
Tuttavia è possibile utilizzare la costruzione from-import per risparmiarci dal dover specificare il nome del modulo prima del’oggetto che ci interessa. In questo modo s’importa l’oggetto o gli oggetti che indichiano nello spazio dei nomi corrente.
			from time import asctime
			print asctime()
Anche se è considerata una cattiva pratica, è anche possibile importare tutti i nomi del modulo allo spazio dei nomi corrente utilizzando il carattere *:
			from time import *
Ora, si ricorderà che, al momento di creare il nostro primo modulo si è insistito sul fatto di salvarlo nella stessa directory dove si trova il programma che lo importava. Allora, come possiamo importare il modulo os, sys e time se i files os.py, sys.py e time.py non trovano nella stessa directory?
Quando s’importa un modulo, Python analizza tutte le directory elencate nella variabile d’ambiente PYTHONPATH per trovare un file con il nome appropriato. Il valore della variabile PYTHONPATH si può visualizzare con Python utilizzando sys.path
			>>> import sys
			>>> sys.path
Così per fare in modo che il nostro modulo sia a disponibile a tutti i programmi del sistema è sufficiente copiarlo in una delle directory elencate nella PYTHONPATH.
Nel caso in cui Python non trova nessun modulo con il nome specificato, lancierebbe un’eccezione di tipo ImportError.
Infine, è interessante notare che i moduli in Python sono anche oggetti, in particolare di tipo module. Naturalmente questo significa che possono avere attributi e metodi. Uno dei suoi attributi, __name__, viene spesso utilizzato per includere codice eseguibile in un modulo, ma che perché questo venga eseguito solo se si chiama il modulo come un programma, e non se s’importa. Per fare questo basta sapere che quando si esegue il modulo direttamente, __name__ ha come valore __main__“, mentre quando viene importato, il valore di __name__ è il nome del modulo:
			print "Si mostra sempre"
			if __name__ == "__main__":
			    print "Si mostra se non è importato"
Un altro attributo interessante è __doc__, che, come nel caso di classi e funzioni, serve come documentazione dell’oggetto (docstring o stringa di documentazione). Il suo valore è quello che si trova nella prima riga del corpo del modulo, nel caso in cui questa riga sia una stringa di testo, in caso contrario sarà uguale a None.
Pacchetti
Se i moduli vengono utilizzati per organizzare il codice, i pacchetti vengono utilizzati per organizzare i moduli. I pacchetti sono tipi speciali di moduli (entrambi sono di tipo module) che consentono di raggruppare i moduli correlati. Mentre i moduli corrispondono fisicamente a i file, i pacchetti sono rappresentati da directory.
In una data applicazione potremmo avere, per esempio, un pacchetto per l’interfaccia ui o un pacchetto bbdd per la persistenza del database.
Per fare che Python tratti a una directory come un pacchetto è necessario creare un file __init__.py in nella directory . In questo file si possono definire elementi che appartengono al pacchetto, come per esempio una costante DRIVER per il pacchetto bbdd, ma che di solito è un file vuoto. Per far sì che un modulo formi parte di un pacchetto è sufficiente copiare il file che definisce il modulo nella directory del pacchetto.
Come i moduli, per importare pacchetti e viene utilizzato anche import e from-import e il carattere . per separare i pacchetti, sottopacchetti e moduli.
			import paq.subpaq.modulo
			paq.subpaq.modulo.func()
Nel corso dei prossimi capitoli vedremo alcuni moduli e pacchetti utili. Per cercare un modulo o un pacchetto che soddisfa una certa nostra necessità, si può consultare la lista PyPI, che ha al momento della stesura di questo documento, ha oltre 4000 pacchetti differenti.


Similari
Overloading di metodi in Java
12% Java
Un metodo overload viene utilizzato per riutilizzare il nome di un metodo ma con argomenti diversi, opzionalmente con un differente tipo di ritorno. [expand title=”Regole per overload” startwrap=”” endwrap=”” excerpt=”⤽” s…
Modi di fare e di non fare in Python
11% Python
Questo documento può essere considerato un compagno del tutorial di Python. Viene illustrato come utilizzare Python, e quasi ancora più importante, come non usare Python. [expand title=”Costrutti del linguaggio che non dov…
redirect 301 usando mod_alias
9% Server
mod_alias è fondamentalmente la versione più semplice di mod_rewrite. Non può fare le cose che fa mod_rewrite, ad esempio modificare la stringa di query. Per eseguire reindirizzamenti nel server web Apache è possibile di u…
Installare Python e Django su Windows
8% Django
Quando ci riferiamo allo sviluppo web con Python, la prima cosa che viene in mente è usare un qualche framework. Il più famoso e utilizzato da tutti è il Django, ma non è l’unico. Ci sono Pylons, Grok, TurboGears e Zope: t…
Metodi magici e costanti predefinite in PHP
8% Php
PHP fornisce un insieme di costanti predefinite e metodi magici per i nostri programmi. A differenza delle normali costanti i quali si impostano con define(), il valore delle costanti predefinite o speciali dipendono da do…