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.

Moduli e script

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:

  1. 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).
  2. 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.
  3. Le directory della standard library, la libreria standard è una directory creata e mantenuta quando viene installato Python.
  4. 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

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.

Import

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.

Lo statement import

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.

parola chiave as

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.

Statement from

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.

parola chiave 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.

Attributo __name__
Attributo __name__

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. 

Package

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.

Il file __init__.py

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.

Search Path

IMPORT DI UN PACKAGE

Import di un Package
Il file __init__.py
#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:

Program

MODULI E PACKAGE IN PYTHON LINK AL CODICE GITHUB

GITHUB

MODULI E PACKAGE IN PYTHON LINK AI POST PRECEDENTI

PREVIOUS POST LINKS