lettura facile

I Package in Python

Un package in Python è come una cartella che contiene più file di codice, chiamati moduli, ognuno dei quali contiene le proprie funzioni, classi e variabili, insieme a codice eseguibile. In altre parole, un package è un insieme di moduli.

In poche parole, puoi pensare a un modulo come a un contenitore. Immagina di avere una scatola grande, quella scatola è il tuo package. Dentro questa scatola, puoi mettere diverse piccole scatole o oggetti, che sono i tuoi moduli. Ogni modulo può contenere funzioni, classi, o variabili – pezzi di codice, insomma, che fanno qualcosa di specifico.

Un package è un tipo di modulo che ha la capacità di contenere altri moduli. Ma non tutti i moduli sono package.

Un modulo diventa un package quando contiene altri moduli, ed è per questo che ha quell'attributo speciale chiamato "__path__".

__path__

Questo attributo è una lista di directory in cui Python può cercare i sottomoduli del package.

Dunque, un package può includere riferimenti a diversi moduli che possono trovarsi nella stessa directory o in cartelle differenti sul computer.

A cosa serve un package? I package ti aiutano a organizzare il tuo codice in modo logico e strutturato. Quando hai un progetto grande, con tante funzionalità diverse, non vuoi certo avere tutto ammassato in un unico file, vero? Ti aiuta a mantenere il codice ordinato, più leggibile e più facile da gestire. Inoltre, se hai due o più moduli con lo stesso nome, puoi indicare con precisare quale vuoi utilizzare indicando il package.

Facciamo un esempio pratico che penso possa chiarire le cose.

Immaginiamo di avere un progetto Python dedicato alla gestione di un piccolo negozio di libri.

Organizziamo il nostro progetto in un package chiamato "libreria". All'interno di questo package, avremo diversi moduli:

  1. inventario.py: Questo modulo si occupa di tenere traccia dei libri disponibili in negozio, di aggiungere o rimuovere titoli dall'inventario, ecc.
  2. vendite.py: Modulo per gestire le transazioni di vendita, applicare sconti, calcolare il totale, ecc.
  3. clienti.py: Si occupa della registrazione dei clienti, del mantenimento dei loro dati, delle preferenze, ecc.

Ogni modulo svolge diverse funzionalità: uno per la gestione dell'inventario, uno per le vendite, uno per la gestione dei clienti, eccetera.

I singoli file, come "inventario.py", "vendite.py", e "clienti.py", sono moduli perché contengono codice Python che può essere riutilizzato, ma non sono package perché non contengono altri moduli al loro interno.

La struttura del nostro package "libreria" potrebbe essere rappresentata così:

libreria/
    __init__.py
    inventario.py
    vendite.py
    clienti.py

In questo caso "libreria" è il nostro package, e come puoi vedere, contiene diversi moduli (inventario.py, vendite.py, clienti.py).

Il file __init__.py è un file speciale che permette a Python di trattare la directory "libreria" come un package. Può essere vuoto, ma la sua presenza è necessaria.

Per utilizzare le funzionalità di questi moduli nel tuo codice, puoi importarli in questo modo:

from libreria import inventario, vendite, clienti
# Ora puoi accedere alle funzioni e classi definite in ciascun modulo
inventario.aggiungi_libro('Il vecchio e il mare', 'Ernest Hemingway')
totale_vendita = vendite.calcola_totale([{'titolo': 'Il vecchio e il mare', 'prezzo': 10.00}])
clienti.aggiungi_cliente('Mario Rossi', 'mario.rossi@stemkb.com')

In questo esempio, "libreria" è un package perché contiene altri moduli e ha l'attributo "__path__" che indica a Python dove cercare i moduli inclusi, ovvero nella cartella /libreria. 

Per indicare il package devi inserire un punto tra il nome del package e quello del modulo.

Ogni riga di codice invoca una funzione da un diverso modulo:

  • La riga di codice inventario.aggiungi_libro('Il vecchio e il mare', 'Ernest Hemingway') invoca la funzione aggiungi_libro() definita nel modulo "inventario", per aggiungere il libro all'elenco dei libri gestiti dall'inventario della libreria.
  • La riga totale_vendita = vendite.calcola_totale([{'titolo': 'Il vecchio e il mare', 'prezzo': 10.00}]) utilizza la funzione calcola_totale() del modulo "vendite" per calcolare il costo totale di un acquisto del libro, e assegna il risultato alla variabile totale_vendita.
  • La riga di codice clienti.aggiungi_cliente('Mario Rossi', 'mario.rossi@stemkb.com') invoca la funzione aggiungi_cliente() dal modulo "clienti", per registrare un nuovo cliente nel sistema di gestione dei clienti della libreria.

Ti faccio un altro esempio di utilizzo dei package.

Immagina di avere un modulo con lo stesso nome in due directory diverse del path di ricerca di Python, puoi indicare quale importare.

Ad esempio, hai due moduli chiamati "mymodule.py". Il primo si trova nella cartella "test1" e il secondo nella cartella "test".

test1/
    __init__.py
    mymodule.py
test2/
    __init__.py
    mymodule.py

Ora digita il comando import per importare mymodule.

import mymodule

Quale dei due moduli viene importato?

In questo caso Python importa il primo modulo che trova nel percorso di ricerca... ma non è detto che sia quello che volevi.

Per evitare questo problema e accedere a quello che ti interessa puoi indicare il package.

import test1.mymodule

oppure

import test2.mymodule

In questo modo, grazie al nome del package riesci ad accedere al modulo corretto.

Tipi di package in Python

Nel linguaggio Python, i package possono essere distinti in due categorie principali:

  • Package Regolari (Regular Packages)
    I package regolari sono quelli che richiedono la presenza di un file `__init__.py` per essere riconosciuti come tali dall'interprete Python. Questo approccio organizza i moduli all'interno di una singola directory. E' l'ideale nelle situazioni in cui l'intero codice relativo al package è contenuto e distribuito come un'unica unità. Un esempio classico di questo tipo di package è una collezione di moduli raggruppati in una singola cartella.
  • Namespace Packages
    I namespace packages, invece, non necessitano del file `__init__.py`. Questa caratteristica li rende in grado di raggruppare moduli situati in più directory, distribuite su percorsi diversi. Grazie alla loro maggiore flessibilità, i namespace packages facilitano lo sviluppo e la distribuzione di parti dello stesso namespace in modo separato, ad esempio, in questo caso le parti del codice possono anche risiedere in cartelle differenti.

Queste due diverse organizzazioni di package ti offrono la possibilità di scegliere l'approccio più adatto alle esigenze del tuo progetto, consentendo sia una distribuzione unitaria sia modulare del codice.

Package di terze parti in Python

Molti package e applicazioni sono sviluppate e messe a disposizione da terze parti, ossia da altri sviluppatori Python.

Questo ti permette di utilizzare dei pacchetti già pronti, senza doverli sviluppare ex novo.

La differenza tra i package e le applicazioni è che queste ultime hanno anche degli script di avvio e dei file di configurazione.

Per utilizzare questi package è necessario prima installarli su Python.

Installazione dei package di terze parti

La maggior parte dei pacchetti Python di terze parti può essere installata utilizzando il gestore di pacchetti pip.

Puoi installare un pacchetto chiamato "pacchetto_esempio", devi eseguire il seguente comando nel terminale:

pip install pacchetto_esempio

Ad esempio, per installare il pacchetto 'requests' che ti permette di compiere richieste HTTP digita:

pip install requests

Utilizzo dei package di terze parti

Dopo l'installazione, puoi utilizzare il pacchetto importandolo nel tuo script Python.

Puoi importare l'intero pacchetto, singoli moduli, o specifiche funzioni/classi dai moduli. Ecco alcuni esempi:

Ad esempio, per importare l'intero pacchetto puoi usare l'istruzione import indicando il nome del pacchetto.

import pacchetto_esempio

Se invece vuoi importare un modulo specifico del pacchetto, puoi indicarlo insieme al nome del pacchetto dopo un punto usato come simbolo separatore.

import pacchetto_esempio.modulo

Puoi anche importare solamente una specifica funzione da un modulo del pacchetto.

In questo caso ti consiglio di usare la sintassi from import:

from pacchetto_esempio.modulo import funzione

Ecco un esempio pratico di utilizzo.

Dopo aver installato il pacchetto 'requests' su Python, puoi richiamarlo tramite l'istruzione import e utilizzare i suoi metodi.

import requests
# Effettua una richiesta GET al sito web
risposta = requests.get('https://www.wikipedia.org')
# Stampa il codice di stato della risposta
print(f'Codice di Stato: {risposta.status_code}')

Questo script importa il pacchetto 'requests' e utilizza il metodo get() del modulo per leggere il contenuto di una pagina web, per poi salvarlo in una variabile.

L'esempio dimostra come i pacchetti in Python possono offrirti funzionalità aggiuntive molto potenti e complesse attraverso un'interfaccia semplice, permettendoti di concentrarti sulla logica del tuo programma senza dover reinventare la ruota ogni volta.

Spero che questo esempio pratico abbia reso l'idea più chiara.




Se qualcosa non ti è chiaro, scrivi la tua domanda nei commenti.




FacebookTwitterLinkedinLinkedin