Programmi python possono essere organizzati in files, contenuti in una gerarchia di directory.
Un file costituisce un "modulo", un insieme di istruzioni e dati auto-consistente. Il nome del file e' il nome del modulo, senza il suffisso, che per files con istruzioni Python e' ".py" . Ma i moduli possono essere in un formato compresso (con zip), ed in questo caso hanno suffisso ".egg" (da Python 2.6), oppure possono essere files compilati, scritti con un altro linguaggio, ed in questo caso hanno suffisso ".so" .
I nomi dei files contenenti i moduli sono soggetti alle stesse regole dei nomi di variabili, infatti Python usa il nome del file, senza suffisso, come riferimento al modulo. Per cui nomi con spazi o caratteri speciali non sono accettati.
I file dei moduli possono iniziare con una stringa che descrive il modulo e viene conservata nell'attributo __doc__ del modulo stesso. Un dizionario con tutti gli oggetti, le variabili e le funzioni del modulo e' messo da Python nell'attributo __dict__ del modulo.
Diversi moduli sono organizzati in "packages", che occupano una directory. Il nome del package e' il nome della directory. Per essere considerata un package una directory deve contenere un file di nome __init__.py , che puo' anche essere vuoto, ma in genere contiene istruzioni che che inizializzano il package.
Un package puo' contenere subpackages, in sottodirectory.
I moduli hanno due funzioni principali:
costituiscono software riutilizzabile
identificano ed isolano un insieme di nomi di oggetti: un modulo definisce infatti uno spazio dei nomi (namespace), in cui python cerca i nomi di variabili, oggetti, funzioni.
Per riferirsi ai nomi del modulo occorre usare il nome del modulo come prefisso. Ad esempio il dizionario __dict__ del modulo sys sara' accessibile con la sintassi: sys.__dict__ .
Python cerca i files con i moduli nella directory corrente, poi nelle directory specificate nella variabile di ambiente: di nome PYTHONPATH , nelle directory delle librerie standard, oppure in directory indicate in un file con estensione .pth , nella directory principale del python (variabile di ambiente PYTHNHOME), infine nelle directory specifica del computer per pacchetti ausiliari (site-packages o dist-packages).
Per vedere i percorsi utilizzati per cercare i moduli si deve esaminare la variabile path del modulo di sistema sys, che contiene la lista delle directory ove si cercano i moduli. Ad esempio, in Linux Debian 7, per Python3, senza aver assegnato PYTHONPATH, si ha:
['', '/usr/lib/python3.2', '/usr/lib/python3.2/plat-linux2', '/usr/lib/python3.2/lib-dynload', '/usr/local/lib/python3.2/dist-packages', '/usr/lib/python3/dist-packages' ]
Per utilizzare un modulo in un programma bisogna "importarlo". In modo che Python possa eseguire il codice del modulo, costruire le classi in esso contenute ed organizzare i nomi degli oggetti. La byte-compilation di un modulo viene effettuata quando il modulo viene caricato.
Il comando per importare un modulo in un file A.py e':
import A
a questo punto oggetti definiti nel file A.py possono essere utilizzati riferendosi ad essi con un nome tipo: A.nomeoggetto
L'istruzione import importa moduli una volta sola nel programma, ulteriori istruzioni import per lo stesso modulo non vengono eseguite.
Per riferirsi agli attributi del modulo usando un prefisso a scelta, invece del nome del modulo si usa la sintassi:
import A as newname
Qui ci si riferisce ad un attributo con: newname.attributo , invece che A.attributo , che non vale piu'.
L'istruzione from permette di importare solo alcuni oggetti da un modulo, ed i nomi vengono inseriti nel namespace corrente, per cui non occorre piu' il nome del modulo come prefisso. La sintassi e':
from nomefile import nome,altronome
Per usare un nome diverso per un oggetto importato:
from nomemodulo import nomeoggetto as altronome, nomeoggetto2 as altronome2
Per importare tutti i nomi del modulo nel namespace corrente:
from nomefile import *
Se il file con il modulo viene modificato occorre reimportare il file e rieseguire l'istruzione from. In Python 2, per ricaricare un modulo c'e' lo statement reload. in Python 3 c'e' una funzione, che fa parte del modulo imp:
import imp
imp.reload(nomemodulo)
Se i moduli sono in una gerarchia di packages (e di directory) si importano con istruzioni tipo:
import nomepackage1.nomepackade2.modulo
Se si vuole importare un package si usa import con il nome della directory del package e Python esegue il file __init__.py che trova in questa directory. Spesso questo file importa i singoli file del package.:
import nomedir
Se si importa un sub-package con un'istruzione tipo:
import nomedir.nomesubdir.nomesubdir
Vengono eseguiti nell'ordine, i files __init__.py che Python trova nelle diverse directory.
Siccome le directory in cui si cercano i moduli sono nella lista path del modulo sys, si possono aggiungere directory a run time con istruzioni tipo:
import sys sys.path.append('/dir/subdir/')
Come esempio poniamo di avere un modulo costituito da un file : Esempio_modulo.py , contenente:
""" Esempio di modulo, che contiene alcuni attributi e classi """ a=1 class A: AinA=32 class B: def __init__(self,u,v): self.x=u self.y=v def printargs(self): print( "args:",self.x,",",self.y )
Si possono importare gli oggetti del modulo ed eseguire le funzioni con:
import Esempio_modulo as Es print( Es.__doc__ ) # stampa la docstring del modulo print( Es.a ) # stampa attributo 'a' del modulo print( Es.A.AinA ) # stampa attributi della classe 'A' ist=Es.B(1,2) # istanzio la classe 'B' ist.printargs() # esegui funzione della classe
Per importare i nomi nel namespace corrente:
from Esempio_modulo import * A.AinA # 'A' e' senza prefisso
Python ha molte funzioni "buitin", che sono proprio parte del linguaggio, come: abs (valore assoluto), len (lunghezza di un array), max,min,sum,pow,print e tante altre, ma oltre a questo Python viene distribuito assieme ad un'ampia collezione di moduli, che costituiscono la libreria standard. I moduli sono moltissimi, l'elenco completo e' in: docs.python.org
Moduli standard, di uso comune sono:
math : con funzioni matematiche sys : parametri dipendenti dal sistema os : interazione con sistema os.path : operazioni su files time : per data ed ora, come anche: datetime,date,timezone string : operazioni su stringhe re : espressioni regolari
Il modulo "math" ha funzioni trigonometriche, esponenziali, logaritmi etc.. Vediamo alcuni esempi:
import math math.pi 3.1415926535897931 math.e 2.7182818284590451 math.sin() : ci sono tutte le funzioni trigonometriche math.ceil(1.4) : 2 # approssimazione per eccesso math.floor(1.7) : 1.0 # approssima per difetto math.factorial(3) : 6 # il fattoriale math.isinf(a) : true se infinito math.isnan(x) : true se x non e' un numero math.log(e) : 1 # logaritmo base e math.log10(10) : 1 # logaritmo base 10 math.pow(2,3) : 8 # esponenziale, come 2**3 math.sqrt(4) : 2 # radice quadrata math.exp(1) : 2.718281828459045 # esponenziale math.degrees(math.pi) : 180 # converte radianti in gradi math.radians(180) :3.141592653589793 # gradi in radianti
Il modulo "time" serve per maneggiare date ed ore. La data e l'ora sono e' conservate in oggetto "time.struct_time", che ha come attributi: giorno, mese, anno, ora etc. abbiamo:
import time time.tzname : ('CET', 'CEST') # fuso orario time.timezone : -3600 time.time() : linux time: numero secondi , da gennaio 1970 time.localtime() : crea oggetto struct_time con l'istante attuale: time.struct_time(tm_year=2022, tm_mon=12, tm_mday=17, tm_hour=21, tm_min=55, tm_sec=10, tm_wday=5, tm_yday=351, tm_isdst=0) la funzione "strftime" formatta un oggetto struct_time time.strftime('%d-%m-%Y',time.localtime()) : '17-12-2022' descrittori di formato: %d giorno %m mese %Y anno %y anno, solo ultime 2 cifre %H ora %M minuti %S secondi la funzione "strptime", crea un oggetto "struct_time" da una stringa: time.strptime('2022-1-1','%Y-%d-%m') : primo gennaio 2022
Il modulo "sys" contiene funzioni per interfaccia con l'ambiente Python, fra queste:
import sys sys.argv : argomenti del programma (per eseguibili python) sys.exit(x) : esce dal programma con codice x sys.modules : moduli caricati sys.path : search path dei moduli sys.ps1 sys.ps : prompt del python sys.version : versione del python sys.stdin : input di default sys.stderr : output per segnalare errori sys.stdout : output di default
Il modulo "os" ha funzioni di interfaccia con il sistema operativo, ha funzioni per gestire i files etc. etc. puo' fare quasi tutto quello che si fa da una shell di Unix:
import os os.system('pwd') : esegue comando di shell: 'pwd' os.environ : variabili di ambiente os.putenv(nome,valore) : aggiunge variabile di ambiente os.uname() : nome del sistema (in Unix)
Il modulo "re" serve per le espressioni regolari, ad esempio:
import re pobj = re.compile('hello[ \t]*(.*)') : crea espressione regolare mobj = pobj.match('hello world!') : fa il match, da True o False mobj.group(1) : sottostringhe espressione regolare
Il modulo "collection" contiene alternative a dizionari, liste e tuple, come "OrderDict" : dizionari ordinati, "namedtuple" : tuple con alementi con nome, ed altri.
"pprint" : serve a stampare strutture dati in modo ben leggibile.
"random" : per numeri casuali
"statistics: medie, mediane, quartili, deviazione standard, regressione, correlazione etc.
"pickle" e "json" sono moduli per la serializzazione (trasformare strutture complesse in stringhe), "tkinter" serve per l'interfaccia al linguaggio "tk" per fare interfacce grafiche,
Ci sono poi moduli per accesso a database, per leggere e scrivere files in formato csv, per costruire applicazioni di rete, per files csv, per comprimere dati, per i threads e tanti altri.
Altri moduli ausiliari si trovano in rete, in pypi.python.org c'e' un vasto indice di moduli. Ci sono programmi appositi (easy_install, pip), per recuperare ed installare packages da questo archivio.
Fra questi moduli ausiliari possono essere utili "numpy" che contiene classi per trattare vettori e matrici; "matplotlib" per fare grafici, "scipy" per trattare dati scientifici, "pandas" per analisi dati.
Il modulo *rpy2* permette di usare il linguaggio R in un programma Python.