Moduli Python
Scopri come funzionano i moduli Python: creane di tuoi, importa con alias, usa from-import, esplora la libreria standard e comprendi sys.path.
Un modulo è un file contenente codice Python — funzioni, classi e variabili — che puoi riutilizzare in più programmi. I moduli sono l'unità base di organizzazione del codice in Python: invece di copiare la logica tra file diversi, la scrivi una volta, la salvi come file .py e la importi ovunque ti serva. Questo capitolo tratta tutto, dalla creazione del tuo primo modulo alla navigazione della libreria standard, fino a come Python individua i moduli in fase di esecuzione.
Cos'è un Modulo Python?
Qualsiasi file .py è un modulo. Quando scrivi:
# greetings.py
def hello(name):
return f"Hello, {name}!"
def goodbye(name):
return f"Goodbye, {name}!"
PI = 3.14159hai creato un modulo chiamato greetings. Il nome del modulo è il nome del file senza l'estensione .py.
I moduli possono contenere:
- Funzioni — blocchi di logica riutilizzabili (vedi Funzioni Python)
- Classi — schemi per gli oggetti (vedi Classi Python)
- Variabili e costanti — dati condivisi
- Istruzioni eseguibili — codice che viene eseguito quando il modulo viene importato o eseguito direttamente
Importare un Modulo
Usa l'istruzione import seguita dal nome del modulo (senza l'estensione .py).
import greetings
print(greetings.hello("Alice")) # Hello, Alice!
print(greetings.goodbye("Alice")) # Goodbye, Alice!
print(greetings.PI) # 3.14159Dopo import greetings, tutti i nomi definiti in greetings.py sono accessibili tramite il prefisso greetings.. Questa notazione a punto previene le collisioni di nomi — la tua variabile PI non può entrare in conflitto con greetings.PI.
Importare Nomi Specifici con from ... import
Se hai bisogno solo di uno o due nomi, importali direttamente in modo da poterli usare senza il prefisso del modulo.
from greetings import hello, PI
print(hello("Bob")) # Hello, Bob!
print(PI) # 3.14159Importare Tutto con *
from greetings import *Questo inserisce tutti i nomi pubblici (quelli che non iniziano con _) nel namespace corrente. Evita questo approccio nei programmi più grandi: inquina il namespace e rende difficile capire da dove proviene un nome.
Alias di Importazione con as
I nomi di modulo lunghi diventano fastidiosi da digitare. Usa as per creare un alias più breve.
import greetings as gr
print(gr.hello("Carol")) # Hello, Carol!Puoi assegnare alias anche ai singoli nomi importati:
from greetings import hello as hi
print(hi("Dave")) # Hello, Dave!Gli alias sono particolarmente comuni con le librerie più diffuse:
import numpy as np
import pandas as pd
import matplotlib.pyplot as pltLa Funzione dir()
dir(module) restituisce un elenco ordinato di tutti i nomi definiti in un modulo — un modo rapido per esplorare ciò che è disponibile.
import math
print(dir(math))
# ['__doc__', '__loader__', ..., 'acos', 'acosh', 'asin', ..., 'sqrt', 'tan', 'tanh', 'tau']Chiama dir() senza argomenti per visualizzare i nomi nel scope corrente.
La Variabile __name__
Ogni modulo ha una variabile built-in chiamata __name__. Quando un file viene importato, __name__ viene impostato al nome del modulo. Quando il file viene eseguito direttamente, __name__ viene impostato alla stringa "__main__".
Questo schema è il modo standard per scrivere codice che viene eseguito solo quando il file è lanciato come script — non quando viene importato come libreria:
# greetings.py
def hello(name):
return f"Hello, {name}!"
if __name__ == "__main__":
# This block only runs when you execute: python greetings.py
print(hello("World"))import greetings # The if-block does NOT run hereQuesto schema è utilizzato in quasi ogni file Python non banale che incontrerai.
Percorso di Ricerca dei Moduli (sys.path)
Quando scrivi import greetings, Python cerca il modulo in un elenco di directory memorizzato in sys.path:
- La directory dello script in esecuzione (o la directory corrente in modalità interattiva)
- Le directory elencate nella variabile d'ambiente
PYTHONPATH - Le directory della libreria standard
- La directory
site-packages(dove risiedono i pacchetti di terze parti installati con pip)
import sys
print(sys.path)
# ['/path/to/script', '/usr/lib/python3.11', ..., '/usr/lib/python3/dist-packages']Puoi aggiungere un percorso in fase di esecuzione, ma questo è raramente necessario per progetti ben strutturati:
import sys
sys.path.append("/path/to/my/libs")La Libreria Standard di Python
Python viene fornito con una vasta libreria standard — centinaia di moduli che coprono tutto, dall'I/O su file ai protocolli di rete, fino alla compressione dei dati. Non devi installare nulla; importali e basta.
math — Funzioni Matematiche
import math
print(math.sqrt(16)) # 4.0
print(math.pi) # 3.141592653589793
print(math.factorial(5)) # 120
print(math.ceil(4.2)) # 5
print(math.floor(4.8)) # 4Vedi Python Math per un riferimento completo.
random — Numeri Casuali
import random
print(random.randint(1, 10)) # random integer between 1 and 10
print(random.choice(["a", "b", "c"])) # random element
print(random.random()) # float in [0.0, 1.0)
numbers = [1, 2, 3, 4, 5]
random.shuffle(numbers)
print(numbers) # shuffled in placedatetime — Date e Orari
import datetime
now = datetime.datetime.now()
print(now) # 2024-03-15 10:30:45.123456
print(now.year) # 2024
print(now.strftime("%B %d, %Y")) # March 15, 2024
today = datetime.date.today()
print(today) # 2024-03-15Vedi Python Dates per una trattazione completa dell'aritmetica delle date e della formattazione.
os e sys — Sistema Operativo e Interprete
import os
print(os.getcwd()) # current working directory
print(os.listdir(".")) # files in the current directory
os.makedirs("new_dir", exist_ok=True) # create a directory
print(os.path.join("folder", "file.txt")) # 'folder/file.txt'import sys
print(sys.version) # Python version string
print(sys.platform) # 'linux', 'darwin', 'win32', etc.
sys.exit(0) # terminate the program with exit code 0json — Codifica e Decodifica JSON
import json
data = {"name": "Alice", "age": 30, "active": True}
# Python → JSON string
json_string = json.dumps(data, indent=2)
print(json_string)
# JSON string → Python
parsed = json.loads(json_string)
print(parsed["name"]) # AliceVedi Python JSON per la lettura e la scrittura su file.
collections — Strutture Dati Specializzate
from collections import Counter, defaultdict
# Count occurrences
words = ["apple", "banana", "apple", "cherry", "banana", "apple"]
counts = Counter(words)
print(counts) # Counter({'apple': 3, 'banana': 2, 'cherry': 1})
print(counts.most_common(2)) # [('apple', 3), ('banana', 2)]
# Dict with default values
scores = defaultdict(int)
scores["Alice"] += 10
scores["Bob"] += 5
print(dict(scores)) # {'Alice': 10, 'Bob': 5}Vedi Python Collections Module per namedtuple, deque e OrderedDict.
Creare un Proprio Modulo
Struttura di Base
I moduli funzionano meglio quando fanno una cosa sola e la fanno bene. Una buona regola pratica: se un gruppo di funzioni condivide un tema, mettile nel loro file.
# mathutils.py
def clamp(value, minimum, maximum):
"""Restrict value to the range [minimum, maximum]."""
return max(minimum, min(value, maximum))
def average(numbers):
"""Return the arithmetic mean of a list of numbers."""
if not numbers:
raise ValueError("Cannot average an empty list")
return sum(numbers) / len(numbers)
def is_prime(n):
"""Return True if n is a prime number."""
if n < 2:
return False
for i in range(2, int(n ** 0.5) + 1):
if n % i == 0:
return False
return True# main.py
from mathutils import clamp, average, is_prime
print(clamp(15, 0, 10)) # 10
print(average([2, 4, 6, 8])) # 5.0
print(is_prime(17)) # TrueDocstring nei Moduli
Aggiungi una docstring a livello di modulo all'inizio del file. Strumenti come help() e i generatori di documentazione la utilizzano.
"""
mathutils.py — Utility functions for common mathematical operations.
Functions:
clamp(value, minimum, maximum) -> number
average(numbers) -> float
is_prime(n) -> bool
"""Variabili di Modulo: __all__
__all__ è un elenco di nomi che dovrebbero essere esportati quando qualcuno esegue from module import *. Funge anche da documentazione sull'API pubblica del modulo.
# mathutils.py
__all__ = ["clamp", "average", "is_prime"]
def _helper(): # leading underscore marks it as private
passRicaricare un Modulo
Python memorizza nella cache i moduli importati in sys.modules. Importare lo stesso modulo due volte non lo riesegue — Python restituisce la versione in cache. Durante lo sviluppo interattivo o il debug puoi forzare un ricaricamento:
import importlib
import greetings
importlib.reload(greetings)Questo è necessario principalmente nelle sessioni REPL o nei notebook Jupyter dopo aver modificato un file di modulo.
Errori Comuni
Importazioni Circolari
Se module_a importa module_b e module_b importa module_a, si ottiene un'importazione circolare. Python riesce a gestire alcune importazioni circolari, ma sono fonte di confusione e spesso indicano un problema di progettazione. La soluzione di solito consiste nel ristrutturare il codice — spostare la logica condivisa in un terzo modulo, o ritardare l'importazione all'interno di una funzione.
Oscurare un Modulo della Libreria Standard
Se chiami il tuo file math.py, random.py o json.py, oscurerai il modulo della libreria standard e manderai in errore qualsiasi codice che lo importa. Usa nomi specifici e descrittivi per i tuoi moduli.
# BAD: naming your file math.py shadows the stdlib
# GOOD: name it mathutils.py or geometry.pyImportError e ModuleNotFoundError
ModuleNotFoundError (una sottoclasse di ImportError) significa che Python non ha trovato il modulo da nessuna parte in sys.path. Cause comuni:
- Un errore di battitura nel nome del modulo
- Il modulo non è installato (
pip install <package-name>) - Il file del modulo si trova in una directory non presente in
sys.path
try:
import nonexistent_module
except ModuleNotFoundError as e:
print(f"Import failed: {e}")
# Import failed: No module named 'nonexistent_module'Moduli vs. Pacchetti
Un modulo è un singolo file .py. Un pacchetto è una directory contenente più moduli e un file __init__.py. I pacchetti consentono di costruire librerie più grandi con una struttura gerarchica. Vedi Python Packages per la trattazione completa.
Moduli di Terze Parti Popolari
Oltre alla libreria standard, l'ecosistema Python su PyPI conta centinaia di migliaia di pacchetti. Installali con pip.
| Pacchetto | Scopo |
|---|---|
numpy | Calcolo numerico, array multidimensionali |
pandas | Analisi e manipolazione dei dati |
matplotlib | Visualizzazione dei dati e grafici |
requests | Richieste HTTP semplificate |
flask / django | Framework web |
scikit-learn | Algoritmi di machine learning |
pytest | Framework di testing |