In questa sezione, esamineremo alcuni dei numerosi moduli di utilità standard di Python per risolvere problemi comuni.
File system: os, os.path, Shutil
I moduli *os* e *os.path* includono molte funzioni per interagire con il file system. Il modulo *shutil* può copiare file.
- documenti del modulo OS
- filenames = os.listdir(dir) -- elenco dei nomi file nel percorso della directory (escluso . e...). I nomi file sono solo i nomi presenti nella directory, non i relativi percorsi assoluti.
- os.path.join(dir, nome file): dato un nome file dall'elenco precedente, utilizza questo per unire la directory e il nome file per creare un percorso
- os.path.expath(percorso): quando viene specificato un percorso, viene restituita una forma assoluta, ad esempio /home/nick/foo/bar.html
- os.path.dirname(path), os.path.basename(path) -- Data dir/foo/bar.html, restituisci il dirname "dir/foo" e basename "bar.html"
- os.path.exists(path) -- true se esiste
- os.mkdir(dir_path): crea una directory, os.makedirs(dir_path) crea tutti i dir necessari in questo percorso
- Shutil.copy(source-path, dest-path): copia un file (devono esistere le directory del percorso dest)
## Example pulls filenames from a dir, prints their relative and absolute paths def printdir(dir): filenames = os.listdir(dir) for filename in filenames: print(filename) ## foo.txt print(os.path.join(dir, filename)) ## dir/foo.txt (relative to current dir) print(os.path.abspath(os.path.join(dir, filename))) ## /home/nick/dir/foo.txt
L'esplorazione di un modulo funziona bene con le funzioni integrate help() e dir() di Python. Nell'interprete, esegui "import os" (importa os) e utilizza questi comandi per vedere cosa è disponibile nel modulo: dir(os), help(os.listdir), dir(os.path), help(os.path.dirname).
Esecuzione di processi esterni -- processo secondario
Il modulo *subprocess* è un modo semplice per eseguire un comando esterno e acquisire il relativo output.
- documenti dei moduli sui processi secondari
- output = subprocess.check_output(cmd, stderr=subprocess.STDOUT) -- esegue il comando, ne attende la chiusura e restituisce il testo di output. Il comando viene eseguito con l'output standard e l'errore standard combinati in un unico testo di output. Se non riesce, genera un CalledProcessError.
- Se desideri un maggiore controllo sull'esecuzione del processo secondario, consulta la classe subprocess.popen
- È presente anche un semplice subprocess.call(cmd) che esegue il comando, scarica l'output nell'output e restituisce il codice di errore. Questa operazione funziona se vuoi eseguire il comando, ma non è necessario acquisire il suo output nelle strutture di dati Python.
import subprocess ## Given a dir path, run an external 'ls -l' on it -- ## shows how to call an external program def listdir(dir): cmd = 'ls -l ' + dir print("Command to run:", cmd) ## good to debug cmd before actually running it (status, output) = subprocess.getstatusoutput(cmd) if status: ## Error case, print the command's output to stderr and exit sys.stderr.write(output) sys.exit(status) print(output) ## Otherwise do something with the command's output
Eccezioni
Un'eccezione rappresenta un errore di runtime che interrompe la normale esecuzione in una determinata riga e trasferisce il controllo al codice di gestione degli errori. Questa sezione introduce solo gli utilizzi basilari delle eccezioni. Ad esempio, un errore di runtime potrebbe essere dovuto al fatto che una variabile utilizzata nel programma non ha un valore (ValueError... probabilmente l'hai visto alcune volte) o un errore dell'apertura del file perché un file non esiste (IOError). Scopri di più nel tutorial sulle eccezioni e consulta l'elenco completo delle eccezioni.
In assenza di codice per la gestione degli errori (come abbiamo fatto finora), un'eccezione di runtime arresta il programma con un messaggio di errore. Si tratta di un buon comportamento predefinito, che hai già visto molte volte. Puoi aggiungere un'opzione "try/eccetto" struttura del codice per gestire le eccezioni, ad esempio:
try: ## Either of these two lines could throw an IOError, say ## if the file does not exist or the read() encounters a low level error. f = open(filename, 'rb') data = f.read() f.close() except IOError: ## Control jumps directly to here if any of the above lines throws IOError. sys.stderr.write('problem reading:' + filename) ## In any case, the code then continues with the line after the try/except
La sezione allow: include il codice che potrebbe generare un'eccezione. La sezione see: contiene il codice da eseguire in caso di eccezione. In assenza di eccezioni, la sezione tranne: viene saltata (ovvero, il codice è solo per la gestione degli errori, non il caso "normale" del codice). Puoi ottenere un puntatore all'oggetto eccezione stesso con la sintassi "ad eccezione di IOError come e: .." (e indica l'oggetto dell'eccezione).
HTTP -- urllib e urlparse
Il modulo *urllib.request* fornisce il recupero degli URL, rendendo un URL simile a un file da cui puoi leggere. Il modulo *urlparse* può smontare e unire gli URL.
- documenti del modulo urllib.request
- ufile = urllib.request.urlopen(url) -- restituisce un file simile all'oggetto per l'URL
- text = ufile.read() -- può leggere da lì, come un file (funzionano anche readlines() e così via)
- info = ufile.info(): il meta info per tale richiesta. info.gettype() è il tipo MIME, ad esempio "text/html"
- baseurl = ufile.geturl() -- ottiene la "base" dell'URL della richiesta, che potrebbe essere diverso dall'originale a causa dei reindirizzamenti
- urllib.request.urlretrieve(url, filename): scarica i dati dell'URL nel percorso file specificato
- urllib.parse.urljoin(baseurl, url) -- Data un URL che può essere o meno completo e la baseurl della pagina da cui proviene, restituisce un URL completo. Usa geturl() sopra per fornire l'URL di base.
Tutte le eccezioni si trovano in urllib.error.
from urllib.request import urlopen ## Given a url, try to retrieve it. If it's text/html, ## print its base url and its text. def wget(url): ufile = urlopen(url) ## get file-like object for url info = ufile.info() ## meta-info about the url content if info.get_content_type() == 'text/html': print('base url:' + ufile.geturl()) text = ufile.read() ## read all its text print(text)
Il codice riportato sopra funziona, ma non include la gestione degli errori se un URL non funziona per qualche motivo. Ecco una versione della funzione che aggiunge la logica test/except per stampare un messaggio di errore se l'operazione sull'URL non riesce.
Se urlopen()
sembra essere in attesa, il sistema potrebbe non consentire l'accesso diretto ad alcune
indirizzi HTTP. Puoi verificarlo provando a recuperare lo stesso URL utilizzando wget
o
curl
. Se anche questi programmi hanno esito negativo, dovrai recuperare il contenuto http attraverso un proxy
completamente gestito di Google Cloud. La configurazione dell'accesso proxy non è spiegata in questo tutorial.
## Version that uses try/except to print an error message if the ## urlopen() fails. def wget2(url): try: ufile = urlopen(url) if ufile.info().get_content_type() == 'text/html': print(ufile.read()) except IOError: print('problem reading url:', url)
Esercizio
Per esercitarti con il materiale del file system e dei comandi esterni, consulta Copia esercizio speciale. Per esercitarti con il materiale urllib, vedi l'Esercizio Puzzle dei log.