Scopo | Elaborare, costruire, controllare ed altro sui nomi di file e percorsi |
Versione Python | 1.4 e superiore |
A partire dal 1 gennaio 2021 le versioni 2.x di Python non sono piu' supportate. Ti invito a consultare la corrispondente versione 3.x dell'articolo per il modulo os.path
Scrivere codice per lavorare con file su multiple piattaforme è facile se si usano le funzioni comprese nel modulo os.path . Anche i programmi che non si intende portare su diverse piattaforme dovrebbero usare os.path per rendere affidabile l'elaborazione dei percorsi.
Il primo gruppo di funzioni in os.path può essere usato per elaborare delle stringhe che rappresentano dei nomi di file dividendole nelle parti che li compongono. E' importante capire che queste funzioni non dipendono dal fatto che questi percorsi esistano. Esse operano solamente sulle stringhe.
L'elaborazione dei percorsi dipende da un pugno di variabili definite nel modulo os:
import os.path
for path in [ '/uno/due/tre/
'/uno/due/tre/',
'/',
'.',
'']:
print '"%s" : "%s"' % (path, os.path.split(path))
$ python ospath_split.py "/uno/due/tre" : "('/uno/due', 'tre')" "/uno/due/tre/" : "('/one/two/tre', '')" "/" : "('/', '')" "." : "('', '.')" "" : "('', '')"
basename()
restituisce un valore che equivale alla seconda parte del risultato di
split()
.
import os.path
for path in [ '/uno/due/tre',
'/uno/due/tre/',
'/',
'.',
'']:
print '"%s" : "%s"' % (path, os.path.basename(path))
$ python ospath_basename.py "/uno/due/tre" : "tre" "/uno/due/tre/" : "" "/" : "" "." : "." "" : ""
dirname()
ritorna il percorso che equivale alla prima parte del risultato di
split()
import os.path
for path in [ '/uno/due/tre',
'/uno/due/tre/',
'/',
'.',
'']:
print '"%s" : "%s"' % (path, os.path.dirname(path))
$ python ospath_dirname.py "/uno/due/tre" : "/uno/due" "/uno/due/tre/" : "/uno/due/tre" "/" : "/" "." : "" "" : ""
splitext()
funziona come split() ma divide il percorso sul separatore di estensione, invece che sui nomi di directory.
import os.path
for path in [ 'nomefile.txt', 'nomefile', '/percorso/al/nomefile.txt', '/', '' ]:
print '"%s" :' % path, os.path.splitext(path)
$ python ospath_splitext.py "nomefile.txt" : ('nomefile', '.txt') "nomefile" : ('nomefile', '') "/percorso/al/nomefile.txt" : ('/percorso/al/nomefile', '.txt') "/" : ('/', '') "" : ('', '')
commonprefix()
prende una lista di percorsi come parametro e restituisce una singola stringa che rappresenta un prefisso comune presente in tutti i percorsi. Il valore potrebbe rappresentare un percorso che in realtà non esiste, ed il separatore di percorso non viene considerato, quindi il prefisso potrebbe non fermarsi nei confini del separatore.
import os.path
paths = ['/uno/due/tre/quattro',
'/uno/due/trequalchealtro',
'/uno/due/tre/',
]
print paths
print os.path.commonprefix(paths)
$ python ospath_commonprefix.py ['/uno/due/tre/quattro', '/uno/due/trequalchealtro', '/uno/due/tre/'] /uno/due/tre
A parte dividere percorsi esistenti, frequentemente occorre costruire percorsi da altre stringhe.
Per combinare diversi componenti di percorso in un singolo valore, si usa
join()
:
import os.path
for parts in [ ('uno', 'due', 'tre'),
('/', 'uno', 'due', 'tre'),
('/uno', '/due', '/tre'),
]:
print parts, ':', os.path.join(*parts)
$ python ospath_join.py ('uno', 'due', 'tre') : uno/due/tre ('/', 'uno', 'due', 'tre') : /uno/due/tre ('/uno', '/due', '/tre') : /tre
E' anche facile lavorare con percorsi che includono componenti inseriti in "variabili" che possono essere espanse automaticamente. Per esempio
expanduser()
converte il carattere tilde (~) nella directory home dell'utente.
import os.path
for user in [ '', 'dhellmann', 'postgres' ]:
lookup = '~' + user
print lookup, ':', os.path.expanduser(lookup)
$ python ospath_expanduser.py ~ : /Users/dhellmann ~dhellmann : /Users/dhellmann ~postgres : /var/empty
expandvars()
è più generico, ed espande ogni variabile di ambiente della shell presente nel percorso
import os.path
import os
os.environ['LA_MIA_VARIABILE'] = 'VALORE'
print os.path.expandvars('/percorso/al/$LA_MIA_VARIABILE')
$ python ospath_expandvars.py /percorso/al/VALORE
I percorsi assemblati da stringhe separate usando
join()
o con variabili incorporate potrebbero risultare con separatori extra o componenti di percorso relativo. L'uso di
normpath()
pulisce tutto:
import os.path
for path in [ 'uno//due//tre',
'uno/./due/./tre',
'uno/../uno/due/tre',
]:
print path, ':', os.path.normpath(path)
$ python ospath_normpath.py uno//due//tre : uno/due/tre uno/./due/./tre : uno/due/tre uno/../uno/due/tre : uno/due/tre
Per convertire un percorso relativo in un nome di file con percorso assoluto si usa
abspath()
.
import os.path
for path in [ '.', '..', './uno/due/tre', '../uno/due/tre']:
print '"%s" : "%s"' % (path, os.path.abspath(path))
$ python ospath_abspath.py "." : "/Users/dhellmann/Documents/PyMOTW/src/PyMOTW/ospath" ".." : "/Users/dhellmann/Documents/PyMOTW/src/PyMOTW" "./uno/due/tre" : "/Users/dhellmann/Documents/PyMOTW/src/PyMOTW/ospath/uno/due/tre" "../uno/due/tre" : "/Users/dhellmann/Documents/PyMOTW/src/PyMOTW/uno/due/tre"
A parte il lavoro con i percorsi,
os.path
include anche qualche funzione per recuperare le proprietà dei file, la qual cosa può essere molto più conveniente che chiamare
os.stat()
:
import os.path
import time
print 'File :', __file__
print 'Ultimo accesso :', time.ctime(os.path.getatime(__file__))
print 'Ultima modifica:', time.ctime(os.path.getmtime(__file__))
print 'Change time :', time.ctime(os.path.getctime(__file__))
print 'Dimensione :', os.path.getsize(__file__)
File : ospath_properties.py Ultimo accesso : Sat Jan 23 13:15:30 2010 Ultima modifica: Sat Jan 23 13:15:26 2010 Change time : Sat Jan 23 13:15:26 2010 Dimensione : 310
Quando un programma trova un nome di percorso, spesso deve sapere se il percorso fa riferimento ad un file o ad una directory. Se si sta lavorando su di una piattaforma che lo supporta, si potrebbe avere bisogno di sapere se il percorso si riferisce ad un link simbolico o ad un punto di montaggio. Si potrebbe anche volere verificare se il percorso esiste o meno. os.path fornisce delle funzioni per verificare tutte queste condizioni.
import os.path
for file in [ __file__, os.path.dirname(__file__), '/', './link_non_valido']:
print "File :", file
print "Assoluto :", os.path.isabs(file)
print "E' un file? :", os.path.isfile(file)
print "E' una directory? :", os.path.isdir(file)
print "E' un Link? :", os.path.islink(file)
print "Punto di montaggio?:", os.path.ismount(file)
print 'Esiste? :', os.path.exists(file)
print 'Esiste il Link? :', os.path.lexists(file)
print
$ ln -s /non/esiste link_non_valido $ python ospath_tests.py File : ospath_tests.py Assoluto : False E' un file? : True E' una directory? : False E' un Link? : False Punto di montaggio?: False Esiste? : True Esiste il Link? : True File : Assoluto : False E' un file? : False E' una directory? : False E' un Link? : False Punto di montaggio?: False Esiste? : False Esiste il Link? : False File : / Assoluto : True E' un file? : False E' una directory? : True E' un Link? : False Punto di montaggio?: True Esiste? : True Esiste il Link? : True File : ./link_non_valido Assoluto : False E' un file? : False E' una directory? : False E' un Link? : True Punto di montaggio?: False Esiste? : False Esiste il Link? : True
os.path.walk()
attraversa tutte le directory in un albero e chiama una funzione che viene fornita alla quale vengono passati il nome della directory ed i nomi del contenuto di quella directory. Questo esempio produce un elenco ricorsivo di directory, ignorando le directory svn.
import os
import os.path
import pprint
def visit(arg, dirname, names):
print dirname, arg
for name in names:
subname = os.path.join(dirname, name)
if os.path.isdir(subname):
print ' %s/' % name
else:
print ' %s' % name
print
os.mkdir('esempio')
os.mkdir('esempio/uno')
f = open('esempio/uno/file.txt', 'wt')
f.write('contenuto')
f.close()
f = open('esempio/due.txt', 'wt')
f.write('contenuto')
f.close()
os.path.walk('esempio', visit, '(Dati utente)')
$ python ospath_walk.py esempio (Dati utente) uno/ due.txt esempio/uno (Dati utente) file.txt
Vedere anche: