Organizzazione del codice

I moduli

Il codice di un programma python può essere utilmente organizzato in moduli. Ad esempio, si può pensare di salvare un file simplemath.py con il seguente codice (ripreso da una lezione precedente):

import math

def input_number(message, accept_float=False):
    """Permette l'inserimento di un numero in maniera controllata.

    Chiede in input una stringa usando *message* come prompt, poi
    tenta la conversione in numero e restituisce il numero
    convertito. Se viene inserito un valore che non è un numero,
    viene richiesto di nuovo l'inserimento.
    Se *accept_float* è vero, accetta anche numeri in virgola mobile.
    """
    while(True):
        v=input(message)
        try:
            if accept_float:
                n=float(v)
            else:
                n=int(v)
            return n
        except ValueError as err:
            print("Sembra che tu non abbia inserito un numero valido…")


def circle_area(radius):
    """Restituisce l'area di un cerchio, dato il raggio *radius*.

    >>> print(circle_area(12))
    452.389342117
    >>> print(circle_area(12.3))
    475.291552562
    """

    assert(isinstance(radius, int) or isinstance(radius, float))
    return radius ** 2 * math.pi


if __name__=="__main__":
    r=input_number("Inserisci il raggio del cerchio: ")
    a=circle_area(r)
    print("L'area di un cerchio di raggio %f è %f." % (r, a))

Come si può notare, il codice del modulo ha due parti: la prima contiene le funzioni definite, mentre la seconda quello che in altri linguaggi di programmazione si chiama "programma principale".

In pratica, se questo codice viene eseguito direttamente, vengono eseguite le istruzioni di richiesta di un numero, calcolo dell'area e output. Se invece il modulo viene importato (vedi esempio successivo), queste istruzioni non vengono eseguite.

Importazione di moduli

L'importazione di un modulo avviene semplicemente indicando il nome del file, senza l'estensione. Tutte le funzioni (e le classi, come vedremo) definite nel file vengono messe a disposizione. Il file importato deve trovarsi nella directory del file principale, oppure in una tra quelle predefinite.

Importazione completa

Se il modulo viene interamente importato, tutte le sue funzioni vengono messe a disposizione. In caso di nomi ripetuti sia nel modulo sia nel codice del proprio file, si può specificare quale funzione usare attraverso la specificazione del modulo:

import simplemath

"""
Importando il modulo simplemath non vengono eseguite le istruzioni
presenti nel "programma principale"
"""

def circle_area(n):
    return 1

if __name__=='__main__':
    for i in range(0,10):
        print(i, simplemath.circle_area(i))
        print(i, circle_area(i))

Importazione solo di alcune funzioni

Se lo si desidera, si possono importare solo alcune funzioni:

from simplemath import circle_area

if __name__=='__main__':
    for i in range(0,10):
        print(i, circle_area(i))

Un esempio completo

Immaginiamo di voler raccogliere in un modulo chiamato usefulfunctions alcune funzioni utili. Sarà sufficiente salvare il file usefulfunctions.py, con un contenuto simile al seguente:

"""
Questo è un modulo che contiene una funzione che somma tutti i
numeri interi presenti in una lista.

Si noti che la funzione contiene un commento che contiene a sua volta
degli esempi di esecuzione con risultato atteso.

Se si esegue il modulo come codice autonomo i test vengono effettivamente svolti.
"""

def sumup(l):
    """Restituisce la somma di tutti i valori interi di una lista o di una tupla

    Tutti i valori non interi vengono ignorati in silenzio.
    Non è ricorsiva: vengono presi in considerazione solo i valori del primo
    livello della lista (o tupla).

    >>> print(sumup((1,3)))
    4
    >>> print(sumup([12, 20, 40.12, 'foo', 13]))
    45
    """

    assert(isinstance(l, (list, tuple)))
    s=0
    for i in l:
        if isinstance(i, int):
            s+=i
    return s

if __name__=='__main__':
    import doctest
    r = doctest.testmod()
    print(r)

Eseguendo questo file viene richiamato il codice indicato alla fine, cioè vengono effettivamente svolti i test di esempio presenti nel commento della funzione:

TestResults(failed=0, attempted=2)

Se in un altro programma abbiamo bisogno della funzione sumup(), non dovremo fare altro che importare il modulo:

import usefulfunctions

def countdown(n, k=100, step=1):
    '''restituisce una lista di *n* valori interi, decrementando a partire da *k*'''
    l=[]
    for i in range(n):
        l.append(k-i*step)
    return l


if __name__=='__main__':
    n=countdown(10,250, 3)
    print(n)
    print('La somma è %d.' % sumup(n))

Il risultato sarà:

[250, 247, 244, 241, 238, 235, 232, 229, 226, 223]
La somma è 2365.

Packages

Volendo, quando il codice comincia a essere complesso e richiede un'organizzazione più complessa, i vari moduli possono essere organizzati in pacchetti (packages).

Un package è in sostanza una directory contenente diversi moduli e un file (__init.py__) che funziona come una sorta di indice e/o file di inizializzazione.

results matching ""

    No results matching ""