MODULI
Nei moduli e package in Python un modulo rappresenta un’organizzazione di codice. E’ un programma che contiene la definizione di dati, funzioni e classi che diventano i suoi attributi. Un modulo forma un namespace che occupa una posizione intermedia nella gerarchia dei namespace. I namespace li abbiamo già trattati.
Viene fatta una distinzione tra i moduli e gli script, uno script rappresenta il flusso principale del programma, i moduli li possiamo considerare come delle librerie di oggetti, contenitori di funzioni e classi principalmente importati tramite l’istruzione import negli script o in altri moduli.
IMPORTAZIONE
L’importazione avviene tramite l’istruzione import, ad esempio:
import modulo1
Quando questo Statement viene incontrato Python esegue una serie di azioni che sono:
- Individuazione del modulo
- Compilazione in Bytecode (se necessario)
- Esecuzione del mudulo
Nel terzo step Python esegue il Bytecode prodotto nella fase di compilazione precedente dall’alto verso il basso un’istruzione alla volta, in questa fase vengono create le funzioni, le classi vengono generati tutti gli attributi in modo tale che possiamo utilizzarli all’interno del file sorgente. Vediamo un po’ più in dettaglio la prima e la seconda fase.
INDIVIDUAZIONE DEL MODULO (MODULE SEARCH PATH)
La sequenza di azioni con cui Python cerca un modulo è la seguente:
- La home directory del programma, cioè la directory dello script che sta importando il modulo. Se viene trovato la ricerca termina e il modulo viene compilato in Bytecode se necessario (ossia se è la prima volta che viene importato oppure il modulo è stato modificato).
- Le directory indicate nella variabile di ambiente PYTHONPATH (se esiste in quanto facoltativa). Se tale variabile è stata impostata Python va a cercare il modulo in tutte le directory indicate in essa. Se viene trovato la ricerca si arresta, altrimenti si passa al punto 3.
- Le directory della standard library, la libreria standard è una directory creata e mantenuta quando viene installato Python.
- Come ultima possibilità, altrimenti significa che abbiamo sbagliato qualcosa, la directory site-packages, che è una sotto cartella della directory in cui è situata la standard library. In questa cartella vengono installati i moduli e framework prodotti da terze parti.
LA TRADUZIONE IN BYTECODE
I moduli ma non gli script producono quando vengono importati un file contente il Bytecode del modulo stesso a cui viene assegnato un nome. Il nome è composto dal nome del modulo compilato, la versione di Python (in questo caso la 3.6) e l’estensione .pyc. Python archivia questi file compilati in Bytecode in una sotto directory rispetto alla directory in cui risiede il modulo chiamata __pycache__. La compilazione in Bytecode viene fatta la prima volta che viene importato il modulo, oppure se la data del file sorgente è posteriore a quella del file compilato, quindi se il file è stato modificato.
LO STATEMENT IMPORT
Si possono importare sulla stessa riga più moduli utilizzando l’istruzione import, ad esempio:
import modulo1, modulo2,….
Come si vede in figura anche un modulo è un oggetto, più precisamente è un’istanza della classe module.
Tutti gli oggetti che andiamo a definire in un modulo sono attributi di quel modulo, myFunc è un attributo dell’oggetto modulo1 e come tale si accede ad esso usando la dot notation. Attraverso l’istruzione import tutti gli elementi costituenti un modulo vengono importati, quindi tutti i suoi attributi, dati, metodi e classi.
LA PAROLA CHIAVE AS
La parola chiave as consente di definire un alias per modulo1. Nel sorgente ci possiamo riferire ad esso con la lettera m.
LO STATEMENT FROM
Serve a importare solo parte del modulo, la parola chiave from ci consente di riferirci nel sorgente ad un attributo usando semplicemente il suo nome, non occorre la dot notation.
EVITARE LE COLLISIONI DEI NOMI
È possibile avendo ogni modulo un diverso namespace, che si verifichino collisioni di nomi, due attributi possono avere lo stesso nome in due moduli distinti in quanto sono distinti anche i namespace. Per evitare questo si può usare l’istruzione as.
L’ATTRIBUTO __NAME__
__name__ è un attributo predefinito dei moduli che Python ci mette a disposizione. Se un modulo viene importato ad esempio modulo1 riferendoci al suo attributo __name__ questi restituisce la stringa “modulo1” proprio perché non deve essere confuso da quando modulo1 viene lanciato dalla linea di comando, dove in questo caso l’attributo __name__ ci restituisce la stringa “__main__”. Ciò è importante in quanto nel modulo1 possiamo effettuare questa distinzione.
I PACKAGE
Un package è una directory che contiene un insieme di moduli. Possono avere una struttura gerarchica formata da directory e sottodirectory. Sono il livello di organizzazione più alto quando strutturiamo il codice Python. Supponiamo di inserire due moduli in una directory dir_c sottodirectory di dir_b.
IL FILE __INIT__.PY
Se noi inseriamo all’interno delle due directory un file chiamato __init__.py questo determina per Python che questa struttura è un package. La presenza di __init__.py è obbligatoria se vogliamo considerare che questo albero di directory sia un package. La struttura è relativa e non assoluta, questo significa che la struttura di directory che costituisce un package deve essere contenuta in una directory facente parte del Module Search Path.
MODULE SEARCH PATH E DIRECTORY
dir_a è la radice di questo package, e consente a Python di localizzarlo, basta aggiungere il path di questa directory nella variabile di ambiente PYTHONPATH. Essa non fa parte del package in quanto non ha il file __init__.py. I file __init__.py contengono il codice di inizializzazione del package, vengono eseguiti una sola volta al momento dell’importazione.
IMPORT DI UN PACKAGE
#CREARE LA SEGUENTE STRUTTURA DI DIRECTORY dir_a/dir_b/dir_c #INSERIRE Modulo1 e Modulo2 in dir_c. CREARE LA VARIABILE D'AMBIENTE #PYTHONPATH CHE PUNTA A dir_a. #FILE myScript.py import dir_b.dir_c.Modulo1 as m1 import dir_b.dir_c.Modulo2 as m2 #MODULO1 result = m1.numeroPrimo(11) print(result) #MODULO2 s = m2.studente('Mario','Rossi',23,'Giurisprudenza',2021) v = s.denominazione() print(v)
#******************************************************************* #IL METODO VERIFICA SE IL NUMERO PASSATO IN INPUT #E' UN NUMERO PRIMO #Modulo1.py def numeroPrimo(numero): divisore = 2 while divisore <= numero: risultato = numero//divisore if divisore > risultato: s=f'{numero} non è un numero primo.' return s if numero % divisore > 0: divisore+=1 continue else: s=f'{numero} è un numero primo.' a=f'divisore: {divisore}' c=f'resto: {numero % divisore}' print(a) print(c) return s
#Modulo2.py class persona(): def __init__(self,nome,cognome,eta): self.__nome__= nome self.__cognome__= cognome self.__eta__ = eta @property def nome(self): return self.__nome__ @nome.setter def nome(self,nome): self.__nome__ = nome @property def cognome(self): return self.__cognome__ @cognome.setter def cognome(self,cognome): self.__cognome__ = cognome @property def eta(self): return self.__eta__ @eta.setter def eta(self,eta): self.__eta__ = eta def denominazione(self): s= f'Persona Nome: {self.nome} Cognome: {self.cognome} età: {self.eta}' return s class studente(persona): def __init__(self,nome,cognome,eta,facolta,anno): self.__facolta__= facolta self.__anno__= anno super().__init__(nome,cognome,eta) @property def facolta(self): return self.__facolta__ @facolta.setter def facolta(self,facolta): self.__facolta__ = facolta @property def anno(self): return self.__anno__ @anno.setter def anno(self,anno): self.__anno__ = anno
VISUALIZZARE GOOGLE MAPS
Con tre righe di codice si può aprire nel Browser di default Google Maps con indirizzo selezionato dinamicamente. Si può anche fare in modo che il programma venga lanciato come se fosse un file eseguibile. Vediamo come fare.
In Visual Studio Code fare click con il tasto destro del mouse su Program.py e selezionare la voce Visualizza in Esplora file. Nella finestra che si apre creare un collegamento a Program.py e modificarlo come in figura:
Lascia un commento