4.7. Importare moduli#
Il meccanismo con cui in python si organizzano progetti software complessi e si
riutilizza il codice è basato sul concetto di modulo. In pratica un modulo è
un file che contiene la definizione di una o più funzioni o classi.
L'importazione può riguardare un intero modulo oppure solo uno (o più) dei suoi
elementi. Tramite i moduli è inoltre possibile utilizzare librerie standard o
sviluppate da terze parti. Consideriamo per esempio la funzione
get_sorted_counts che abbiamo appena scritto: se esistesse un dizionario in
cui le chiavi inesistenti venissero automaticamente associate a un valore
nullo, si potrebbe semplificare notevolmente il corpo della funzione, rendendo
corretto il primo tentativo di implementazione che avevamo fatto. In effetti,
una tale variante di dizionario esiste: si chiama defaultdict ed è
disponibile nel modulo collections (uno dei moduli standard di python). La
cella seguente importa questo nuovo tipo di dato:
from collections import defaultdict
e lo mette a disposizione: l'espressione defaultdict(<tipo>) crea un
dizionario vuoto e il tipo indicato come argomento determina quale sarà il
valore predefinito per le chiavi. Nel nostro caso, l'argomento int fa sì che
tale valore predefinito sia 0. Ciò permette di riscrivere la funzione
get_sorted_counts in modo che non sia più necessario verificare
preventivamente l'esistenza dei contatori.
def get_sorted_counts(sequence):
counts = defaultdict(int)
for x in sequence:
counts[x] += 1
pairs = counts.items()
return sorted(pairs, key=lambda p:p[1], reverse=True)
Quando è necessario importare molti elementi da uno o più moduli, potrebbe capitare che due o più elementi in moduli diversi abbiano lo stesso nome. Per evitare situazioni di questo genere, è opportuno importare un intero modulo: per esempio, l'istruzione
import numpy
importa il modulo corrispondente alla libreria numpy,
che mette a disposizione una struttura dati simile agli array (in cui
l'omogeneità dei dati ivi contenuti permette di effettuare calcoli in modo
più efficiente rispetto all'uso delle liste o delle tuple). Dopo che un
modulo è stato importato, è possibile accedere a un suo generico elemento
usando il nome del modulo, seguito da un punto e dal nome dell'elemento in
questione. Per esempio, la cella successiva calcola il cosiddetto argmax
della lista index (dopo averla modificata eliminando i valori None in
essa presenti), e cioè l'indice in cui si trova un suo elemento massimo.
years = [1941, 1962, None, None, 1941,
1964, None, 1940, 1941, 1961,
None, 1963, None, 1963, 1981,
None, None, 1962, 1979]
years = [y for y in years if y]
numpy.argmax(years)
np.int64(9)
Indicare il nome di un modulo per poter accedere ai suoi elementi ha spesso
l'effetto di allungare il codice, diminuendone al contempo la leggibilità. È
per questo motivo che è possibile importare un modulo specificando un nome
alternativo, più corto. È quello che succede nella seguente cella, che importa
numpy e pandas, un modulo che mette a
disposizione delle classi per gestire i dati organizzandoli in serie e in
tabelle.
import numpy as np
import pandas as pd
Nomenclatura
Questo modo di importare numpy e pandas usando i nomi alternativi np e pd
fa riferimento a una convenzione molto diffusa tra gli sviluppatori. Vale la
pena mantenre questa convenzione, così che chi legge il codice possa capire a
colpo d'occhio a quale modulo si fa riferimento.
I moduli più complessi sono organizzati in strutture gerarchiche chiamate
package, in modo non dissimile a quanto avviene per esempio in Java. La
seguente cella importa il modulo pyplot che è contenuto nel modulo
matplotlib (matplotlib è la libreria di riferimento
in python per la creazione di grafici).
import matplotlib.pyplot as plt