# 6. Moduli

Se chiudi l’interprete Python e lo riapri, le definizioni che hai fatto (funzioni e variabili) vengono perse. Pertanto, se vuoi scrivere un programma un po” più lungo, è meglio usare un editor di testo per preparare l’input per l’interprete e eseguirlo con quel file come input. Questo è conosciuto come creare uno script. Man mano che il tuo programma diventa più lungo, potresti volerlo dividere in diversi file per una manutenzione più facile. Potresti anche voler usare una funzione utile che hai scritto in diversi programmi senza copiarne la definizione in ciascun programma.

Per supportare questo, Python ha un modo per mettere definizioni in un file e usarle in uno script o in un’istanza interattiva dell’interprete. Tale file è chiamato un modulo; le definizioni di un modulo possono essere importate in altri moduli o nel modulo principale (la collezione di variabili a cui hai accesso in uno script eseguito al livello superiore e in modalità calcolatrice).

Un modulo è un file contenente definizioni e istruzioni Python. Il nome del file è il nome del modulo con il suffisso `.py` aggiunto. All’interno di un modulo, il nome del modulo (come stringa) è disponibile come valore della variabile globale `__name__`. Ad esempio, usa il tuo editor di testo preferito per creare un file chiamato `fibo.py` nella directory corrente con il seguente contenuto:

    # Fibonacci numbers module

    def fib(n):    # write Fibonacci series up to n
        a, b = 0, 1
        while a < n:
            print(a, end=' ')
            a, b = b, a+b
        print()

    def fib2(n):   # return Fibonacci series up to n
        result = []
        a, b = 0, 1
        while a < n:
            result.append(a)
            a, b = b, a+b
        return result

Ora entra nell’interprete Python e importa questo modulo con il seguente comando:

    >>> import fibo

Questo non aggiunge i nomi delle funzioni definite in `fibo` direttamente all’attuale namespace (vedi Visibilità e spazi dei nomi in Python per maggiori dettagli); aggiunge solo il nome del modulo `fibo` lì. Utilizzando il nome del modulo puoi accedere alle funzioni:

    >>> fibo.fib(1000)
    0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987
    >>> fibo.fib2(100)
    [0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]
    >>> fibo.__name__
    'fibo'

Se intendi usare una funzione spesso puoi assegnarla a un nome locale:

    >>> fib = fibo.fib
    >>> fib(500)
    0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

## 6.1. Più sui Moduli

Un modulo può contenere istruzioni eseguibili così come definizioni di funzioni. Queste istruzioni sono intese per inizializzare il modulo. Sono eseguite solo la prima volta che il nome del modulo viene incontrato in un’istruzione d’importazione. [1] (Sono anche eseguite se il file è eseguito come script.)

Ogni modulo ha il proprio namespace privato, che è utilizzato come il namespace globale da tutte le funzioni definite nel modulo. Pertanto, l’autore di un modulo può usare variabili globali nel modulo senza preoccuparsi di collisioni accidentali con le variabili globali di un utente. D’altra parte, se sai quello che stai facendo puoi toccare le variabili globali di un modulo con la stessa notazione utilizzata per riferirsi alle sue funzioni, `modname.itemname`.

I moduli possono importare altri moduli. È consuetudine, ma non obbligatorio, posizionare tutte le istruzioni `import` all’inizio di un modulo (o script, se è per questo). I nomi dei moduli importati, se posizionati a livello superiore di un modulo (fuori da qualsiasi funzione o classe), sono aggiunti al namespace globale del modulo.

Esiste una variante dell’istruzione `import` che importa nomi da un modulo direttamente nel namespace del modulo importante. Ad esempio:

    >>> from fibo import fib, fib2
    >>> fib(500)
    0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

Questo non introduce il nome del modulo da cui provengono le importazioni nel namespace locale (quindi nell’esempio, `fibo` non è definito).

Esiste anche una variante per importare tutti i nomi che un modulo definisce:

    >>> from fibo import *
    >>> fib(500)
    0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

Questo importa tutti i nomi eccetto quelli che iniziano con un underscore (`_`). Nella maggior parte dei casi i programmatori Python non utilizzano questa funzione poiché introduce un insieme sconosciuto di nomi nell’interprete, nascondendo possibilmente alcune cose che hai già definito.

Nota che in generale la pratica di importare `*` da un modulo o pacchetto è disapprovata, poiché spesso causa codice poco leggibile. Tuttavia, è accettabile usarla per risparmiare battitura nelle sessioni interattive.

Se il nome del modulo è seguito da `as`, allora il nome che segue `as` è legato direttamente al modulo importato.

    >>> import fibo as fib
    >>> fib.fib(500)
    0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

Questo importa effettivamente il modulo nello stesso modo in cui lo farebbe `import fibo`, con l’unica differenza che sarà disponibile come `fib`.

Può anche essere utilizzato quando si utilizza `from` con effetti simili:

    >>> from fibo import fib as fibonacci
    >>> fibonacci(500)
    0 1 1 2 3 5 8 13 21 34 55 89 144 233 377

Nota

Per ragioni di efficienza, ogni modulo viene importato una sola volta per sessione dell’interprete. Pertanto, se cambi i tuoi moduli, devi riavviare l’interprete – o, se è solo un modulo che vuoi testare interattivamente, usa `importlib.reload()`, es. `import importlib; importlib.reload(modulename)`.

### 6.1.1. Esecuzione di moduli come script

Quando esegui un modulo Python con

    python fibo.py <arguments>

il codice nel modulo sarà eseguito, proprio come se lo avessi importato, ma con `__name__` impostato su `"__main__"`. Ciò significa che aggiungendo questo codice alla fine del tuo modulo:

    if __name__ == "__main__":
        import sys
        fib(int(sys.argv[1]))

puoi rendere il file utilizzabile sia come script che come modulo importabile, poiché il codice che analizza la linea di comando viene eseguito solo se il modulo è eseguito come file «principale»:

    $ python fibo.py 50
    0 1 1 2 3 5 8 13 21 34

Se il modulo è importato, il codice non viene eseguito:

    >>> import fibo
    >>>

Questo è spesso usato sia per fornire un’interfaccia utente comoda a un modulo, sia per scopi di test (eseguire il modulo come script esegue una suite di test).

### 6.1.2. Il percorso di ricerca del modulo

Quando un modulo chiamato `spam` è importato, l’interprete cerca prima un modulo built-in con quel nome. Questi nomi di moduli sono elencati in `sys.builtin_module_names`. Se non viene trovato, allora cerca un file chiamato `spam.py` in una lista di directory data dalla variabile `sys.path`. `sys.path` è inizializzata da queste posizioni:

- La directory contenente lo script di input (o la directory corrente quando non è specificato alcun file).

- `PYTHONPATH` (una lista di nomi di directory, con la stessa sintassi della variabile di shell `PATH`).

- Il valore predefinito dipendente dall’installazione (per convenzione include una directory `site-packages`, gestita dal modulo `site`).

Maggiori dettagli sono disponibili in The initialization of the sys.path module search path.

Nota

Su file system che supportano i collegamenti simbolici, la directory contenente lo script di input viene calcolata dopo che il collegamento simbolico è stato seguito. In altre parole la directory contenente il collegamento simbolico non è aggiunta al percorso di ricerca del modulo.

Dopo l’inizializzazione, i programmi Python possono modificare `sys.path`. La directory contenente lo script in esecuzione è posizionata all’inizio del percorso di ricerca, davanti al percorso della libreria standard. Ciò significa che gli script in quella directory saranno caricati invece dei moduli con lo stesso nome nella directory della libreria. Questo è un errore a meno che la sostituzione non sia intenzionale. Vedi la sezione Moduli Standard per maggiori informazioni.

### 6.1.3. File Python «compilati»

Per velocizzare il caricamento dei moduli, Python memorizza nella cache la versione compilata di ciascun modulo nella directory `__pycache__` sotto il nome `module.version.pyc`, dove la versione codifica il formato del file compilato; contiene generalmente il numero di versione di Python. Ad esempio, nella versione CPython 3.3, la versione compilata di spam.py verrebbe memorizzata nella cache come `__pycache__/spam.cpython-33.pyc`. Questa convenzione di denominazione permette ai moduli compilati di versioni diverse e rilasci diversi di Python di coesistere.

Python controlla la data di modifica della sorgente rispetto alla versione compilata per vedere se è obsoleta e deve essere ricompilata. Questo è un processo completamente automatico. Inoltre, i moduli compilati sono indipendenti dalla piattaforma, quindi la stessa libreria può essere condivisa tra sistemi con diverse architetture.

Python non controlla la cache in due circostanze. Primo, ricompila sempre e non memorizza il risultato per il modulo caricato direttamente dalla linea di comando. Secondo, non controlla la cache se non esiste il modulo sorgente. Per supportare una distribuzione senza sorgente (solo compilata), il modulo compilato deve essere nella directory sorgente e non deve esserci un modulo sorgente.

Alcuni consigli per esperti:

- Puoi usare le opzioni `-O` o `-OO` sul comando Python per ridurre la dimensione di un modulo compilato. L’opzione `-O` rimuove le istruzioni assert, l’opzione `-OO` rimuove sia le istruzioni assert che le stringhe __doc__. Poiché alcuni programmi possono fare affidamento su queste, dovresti usare questa opzione solo se sai quello che stai facendo. I moduli «ottimizzati» hanno un tag `opt-` e sono solitamente più piccoli. I futuri rilasci possono cambiare gli effetti dell’ottimizzazione.

- Un programma non gira più velocemente quando è letto da un file `.pyc` rispetto a quando è letto da un file `.py`; l’unica cosa che è più veloce nei file `.pyc` è la velocità con cui vengono caricati.

- Il modulo `compileall` può creare file .pyc per tutti i moduli in una directory.

- Ci sono maggiori dettagli su questo processo, incluso un diagramma di flusso delle decisioni, in PEP 3147.

## 6.2. Moduli Standard

Python viene fornito con una libreria di moduli standard, descritta in un documento separato, il Python Library Reference («Library Reference» da qui in avanti). Alcuni moduli sono incorporati nell’interprete; questi forniscono accesso a operazioni che non fanno parte del core del linguaggio ma sono comunque incorporate, sia per efficienza che per fornire accesso a primitive del sistema operativo come le chiamate di sistema. Il set di tali moduli è un’opzione di configurazione che dipende anche dalla piattaforma sottostante. Ad esempio, il modulo `winreg` è fornito solo sui sistemi Windows. Un particolare modulo merita attenzione: `sys`, che è incorporato in ogni interprete Python. Le variabili `sys.ps1` e `sys.ps2` definiscono le stringhe usate come prompt primario e secondario:

    >>> import sys
    >>> sys.ps1
    '>>> '
    >>> sys.ps2
    '... '
    >>> sys.ps1 = 'C> '
    C> print('Yuck!')
    Yuck!
    C>

Queste due variabili sono definite solo se l’interprete è in modalità interattiva.

La variabile `sys.path` è una lista di stringhe che determina il percorso di ricerca dell’interprete per i moduli. È inizializzata a un percorso predefinito preso dalla variabile di ambiente `PYTHONPATH`, o da un predefinito incorporato se `PYTHONPATH` non è impostato. Puoi modificarla usando le operazioni standard delle liste:

    >>> import sys
    >>> sys.path.append('/ufs/guido/lib/python')

## 6.3. La funzione `dir()`

La funzione built-in `dir()` è usata per scoprire quali nomi definisce un modulo. Restituisce una lista ordinata di stringhe:

    >>> import fibo, sys
    >>> dir(fibo)
    ['__name__', 'fib', 'fib2']
    >>> dir(sys)
    ['__breakpointhook__', '__displayhook__', '__doc__', '__excepthook__',
     '__interactivehook__', '__loader__', '__name__', '__package__', '__spec__',
     '__stderr__', '__stdin__', '__stdout__', '__unraisablehook__',
     '_clear_type_cache', '_current_frames', '_debugmallocstats', '_framework',
     '_getframe', '_git', '_home', '_xoptions', 'abiflags', 'addaudithook',
     'api_version', 'argv', 'audit', 'base_exec_prefix', 'base_prefix',
     'breakpointhook', 'builtin_module_names', 'byteorder', 'call_tracing',
     'callstats', 'copyright', 'displayhook', 'dont_write_bytecode', 'exc_info',
     'excepthook', 'exec_prefix', 'executable', 'exit', 'flags', 'float_info',
     'float_repr_style', 'get_asyncgen_hooks', 'get_coroutine_origin_tracking_depth',
     'getallocatedblocks', 'getdefaultencoding', 'getdlopenflags',
     'getfilesystemencodeerrors', 'getfilesystemencoding', 'getprofile',
     'getrecursionlimit', 'getrefcount', 'getsizeof', 'getswitchinterval',
     'gettrace', 'hash_info', 'hexversion', 'implementation', 'int_info',
     'intern', 'is_finalizing', 'last_traceback', 'last_type', 'last_value',
     'maxsize', 'maxunicode', 'meta_path', 'modules', 'path', 'path_hooks',
     'path_importer_cache', 'platform', 'prefix', 'ps1', 'ps2', 'pycache_prefix',
     'set_asyncgen_hooks', 'set_coroutine_origin_tracking_depth', 'setdlopenflags',
     'setprofile', 'setrecursionlimit', 'setswitchinterval', 'settrace', 'stderr',
     'stdin', 'stdout', 'thread_info', 'unraisablehook', 'version', 'version_info',
     'warnoptions']

Senza argomenti, `dir()` elenca i nomi che hai definito attualmente:

    >>> a = [1, 2, 3, 4, 5]
    >>> import fibo
    >>> fib = fibo.fib
    >>> dir()
    ['__builtins__', '__name__', 'a', 'fib', 'fibo', 'sys']

Nota che elenca tutti i tipi di nomi: variabili, moduli, funzioni, ecc.

`dir()` non elenca i nomi delle funzioni e variabili built-in. Se vuoi una lista di questi, sono definiti nel modulo standard `builtins`:

    >>> import builtins
    >>> dir(builtins)
    ['ArithmeticError', 'AssertionError', 'AttributeError', 'BaseException',
     'BlockingIOError', 'BrokenPipeError', 'BufferError', 'BytesWarning',
     'ChildProcessError', 'ConnectionAbortedError', 'ConnectionError',
     'ConnectionRefusedError', 'ConnectionResetError', 'DeprecationWarning',
     'EOFError', 'Ellipsis', 'EnvironmentError', 'Exception', 'False',
     'FileExistsError', 'FileNotFoundError', 'FloatingPointError',
     'FutureWarning', 'GeneratorExit', 'IOError', 'ImportError',
     'ImportWarning', 'IndentationError', 'IndexError', 'InterruptedError',
     'IsADirectoryError', 'KeyError', 'KeyboardInterrupt', 'LookupError',
     'MemoryError', 'NameError', 'None', 'NotADirectoryError', 'NotImplemented',
     'NotImplementedError', 'OSError', 'OverflowError',
     'PendingDeprecationWarning', 'PermissionError', 'ProcessLookupError',
     'ReferenceError', 'ResourceWarning', 'RuntimeError', 'RuntimeWarning',
     'StopIteration', 'SyntaxError', 'SyntaxWarning', 'SystemError',
     'SystemExit', 'TabError', 'TimeoutError', 'True', 'TypeError',
     'UnboundLocalError', 'UnicodeDecodeError', 'UnicodeEncodeError',
     'UnicodeError', 'UnicodeTranslateError', 'UnicodeWarning', 'UserWarning',
     'ValueError', 'Warning', 'ZeroDivisionError', '_', '__build_class__',
     '__debug__', '__doc__', '__import__', '__name__', '__package__', 'abs',
     'all', 'any', 'ascii', 'bin', 'bool', 'bytearray', 'bytes', 'callable',
     'chr', 'classmethod', 'compile', 'complex', 'copyright', 'credits',
     'delattr', 'dict', 'dir', 'divmod', 'enumerate', 'eval', 'exec', 'exit',
     'filter', 'float', 'format', 'frozenset', 'getattr', 'globals', 'hasattr',
     'hash', 'help', 'hex', 'id', 'input', 'int', 'isinstance', 'issubclass',
     'iter', 'len', 'license', 'list', 'locals', 'map', 'max', 'memoryview',
     'min', 'next', 'object', 'oct', 'open', 'ord', 'pow', 'print', 'property',
     'quit', 'range', 'repr', 'reversed', 'round', 'set', 'setattr', 'slice',
     'sorted', 'staticmethod', 'str', 'sum', 'super', 'tuple', 'type', 'vars',
     'zip']

## 6.4. Pacchetti

I pacchetti sono un modo di strutturare il namespace dei moduli di Python usando «nomi di moduli puntati». Ad esempio, il nome del modulo `A.B` designa un sottomodulo chiamato `B` in un pacchetto chiamato `A`. Proprio come l’uso dei moduli salva gli autori di diversi moduli dal preoccuparsi dei nomi delle variabili globali degli altri, l’uso dei nomi di moduli puntati salva gli autori di pacchetti multi-modulo come NumPy o Pillow dal preoccuparsi dei nomi dei moduli degli altri.

Supponiamo che tu voglia progettare una collezione di moduli (un «pacchetto») per la gestione uniforme dei file audio e dei dati audio. Ci sono molti formati di file audio diversi (di solito riconosciuti dalla loro estensione, ad esempio: `.wav`, `.aiff`, `.au`), quindi potresti aver bisogno di creare e mantenere una collezione crescente di moduli per la conversione tra i vari formati di file. Ci sono anche molte operazioni diverse che potresti voler eseguire sui dati audio (come il mixaggio, l’aggiunta di eco, l’applicazione di una funzione equalizzatrice, la creazione di un effetto stereo artificiale), quindi, in aggiunta, scriverai una serie interminabile di moduli per eseguire queste operazioni. Ecco una possibile struttura per il tuo pacchetto (espressa in termini di filesystem gerarchico):

    sound/                          Top-level package
          __init__.py               Initialize the sound package
          formats/                  Subpackage for file format conversions
                  __init__.py
                  wavread.py
                  wavwrite.py
                  aiffread.py
                  aiffwrite.py
                  auread.py
                  auwrite.py
                  ...
          effects/                  Subpackage for sound effects
                  __init__.py
                  echo.py
                  surround.py
                  reverse.py
                  ...
          filters/                  Subpackage for filters
                  __init__.py
                  equalizer.py
                  vocoder.py
                  karaoke.py
                  ...

Quando importa il pacchetto, Python cerca nelle directory su `sys.path` cercando la sottodirectory del pacchetto.

I file `__init__.py` sono richiesti per fare in modo che Python tratti le directory contenenti il file come pacchetti (a meno che non si utilizzi un namespace package, una funzionalità relativamente avanzata). Questo impedisce alle directory con un nome comune, come `string`, di nascondere inavvertitamente moduli validi che si trovano più avanti nel percorso di ricerca del modulo. Nel caso più semplice, `__init__.py` può essere solo un file vuoto, ma può anche eseguire codice di inizializzazione per il pacchetto o impostare la variabile `__all__`, descritta più avanti.

Gli utenti del pacchetto possono importare moduli individuali dal pacchetto, ad esempio:

    import sound.effects.echo

Questo carica il sottomodulo `sound.effects.echo`. Deve essere referenziato con il suo nome completo.:

    sound.effects.echo.echofilter(input, output, delay=0.7, atten=4)

Un modo alternativo di importare il sottomodulo è:

    from sound.effects import echo

Questo carica anche il sottomodulo `echo`, e lo rende disponibile senza il prefisso del pacchetto, quindi può essere usato come segue:

    echo.echofilter(input, output, delay=0.7, atten=4)

Un’ulteriore variazione è importare direttamente la funzione o la variabile desiderata:

    from sound.effects.echo import echofilter

Ancora una volta, questo carica il sottomodulo `echo`, ma rende direttamente disponibile la sua funzione `echofilter()`:

    echofilter(input, output, delay=0.7, atten=4)

Nota che quando usi `from package import item`, l’elemento può essere un sottomodulo (o sottopacchetto) del pacchetto, o qualche altro nome definito nel pacchetto, come una funzione, classe o variabile. L’istruzione `import` testa prima se l’elemento è definito nel pacchetto; se non lo è, assume che sia un modulo e tenta di caricarlo. Se non riesce a trovarlo, viene sollevata un’eccezione `ImportError`.

Al contrario, quando usi una sintassi come `import item.subitem.subsubitem`, ciascun elemento tranne l’ultimo deve essere un pacchetto; l’ultimo elemento può essere un modulo o un pacchetto ma non può essere una classe, funzione o variabile definita nell’elemento precedente.

### 6.4.1. Importare * Da un Pacchetto

Ora cosa succede quando l’utente scrive `from sound.effects import *`? Idealmente, si spera che questo vada in qualche modo nel filesystem, trovi quali sottomoduli sono presenti nel pacchetto e li importi tutti. Questo potrebbe richiedere molto tempo e l’importazione di sottomoduli potrebbe avere effetti collaterali indesiderati che dovrebbero accadere solo quando il sottomodulo viene importato esplicitamente.

L’unica soluzione è che l’autore del pacchetto fornisca un indice esplicito del pacchetto. L’istruzione `import` utilizza la seguente convenzione: se il codice di `__init__.py` di un pacchetto definisce una lista denominata `__all__`, essa è considerata la lista dei nomi dei moduli che dovrebbero essere importati quando si incontra `from package import *`. È compito dell’autore del pacchetto mantenere aggiornata questa lista quando viene rilasciata una nuova versione del pacchetto. Gli autori dei pacchetti possono anche decidere di non supportarla, se non vedono un’utilità per l’importazione * dal loro pacchetto. Ad esempio, il file `sound/effects/__init__.py` potrebbe contenere il seguente codice:

    __all__ = ["echo", "surround", "reverse"]

Questo significherebbe che `from sound.effects import *` importerebbe i tre sottomoduli denominati del pacchetto `sound.effects`.

Tieni presente che i sottomoduli potrebbero essere ombreggiati da nomi definiti localmente. Ad esempio, se aggiungi una funzione `reverse` al file `sound/effects/__init__.py`, `from sound.effects import *` importerebbe solo i due sottomoduli `echo` e `surround`, ma non il sottomodulo `reverse`, perché è oscurato dalla funzione `reverse` definita localmente.:

    __all__ = [
        "echo",      # refers to the 'echo.py' file
        "surround",  # refers to the 'surround.py' file
        "reverse",   # !!! refers to the 'reverse' function now !!!
    ]

    def reverse(msg: str):  # <-- this name shadows the 'reverse.py' submodule
        return msg[::-1]    #     in the case of a 'from sound.effects import *'

Se `__all__` non è definito, l’istruzione `from sound.effects import *` non importa tutti i sottomoduli del pacchetto `sound.effects` nello spazio dei nomi corrente; si limita ad assicurare che il pacchetto `sound.effects` sia stato importato (eventualmente eseguendo qualsiasi codice di inizializzazione in `__init__.py`) e quindi importa solo i nomi definiti nel pacchetto. Questo include qualsiasi nome definito (e sottomoduli esplicitamente caricati) nel file `__init__.py`. Include anche eventuali sottomoduli del pacchetto che sono stati esplicitamente caricati da precedenti istruzioni di `import`. Considera questo codice:

    import sound.effects.echo
    import sound.effects.surround
    from sound.effects import *

In questo esempio, i moduli `echo` e `surround` sono importati nello spazio dei nomi corrente perché sono definiti nel pacchetto `sound.effects` quando viene eseguita l’istruzione `from...import`. (Questo funziona anche quando è definito `__all__`.)

Sebbene certi moduli siano progettati per esportare solo nomi che seguono certi schemi quando usi `import *`, è comunque considerata una cattiva pratica nel codice di produzione.

Ricorda, non c’è nulla di sbagliato nell’usare `from package import specific_submodule`! Infatti, questa è la notazione raccomandata a meno che il modulo importante non debba usare sottomoduli con lo stesso nome da pacchetti differenti.

### 6.4.2. Riferimenti Intra-pacchetto

Quando i pacchetti sono strutturati in sottopacchetti (come il pacchetto `sound` nell’esempio), puoi usare importazioni assolute per riferirti a sottomoduli di pacchetti fratelli. Ad esempio, se il modulo `sound.filters.vocoder` deve utilizzare il modulo `echo` nel pacchetto `sound.effects`, può usare `from sound.effects import echo`.

Puoi anche scrivere importazioni relative, con la forma dell’istruzione di importazione `from module import name`. Queste importazioni utilizzano punti di testa per indicare i pacchetti corrente e genitore coinvolti nell’importazione relativa. Dal modulo `surround`, ad esempio, potresti usare:

    from . import echo
    from .. import formats
    from ..filters import equalizer

Nota che le importazioni relative si basano sul nome del modulo corrente. Poiché il nome del modulo principale è sempre `"__main__"`, i moduli destinati all’uso come modulo principale di un’applicazione Python devono sempre usare importazioni assolute.

### 6.4.3. Pacchetti in Directory Multiple

I pacchetti supportano un altro attributo speciale, `__path__`. Questo è inizializzato per essere una lista contenente il nome della directory che contiene il `__init__.py` prima che il codice in quel file venga eseguito. Questa variabile può essere modificata; farlo influenza le ricerche future per moduli e sottopacchetti contenuti nel pacchetto.

Sebbene questa funzione non sia spesso necessaria, può essere utilizzata per estendere il set di moduli trovati in un pacchetto.

Note

[1]

In realtà anche le definizioni di funzione sono “istruzioni” che vengono “eseguite”; l’esecuzione di una definizione di funzione a livello di modulo aggiunge il nome della funzione allo spazio dei nomi globale del modulo.