Le module os.path permet toutes sortes de manipulations, indépendantes de la plateforme, des noms de fichier.
Source : PyMOTW.
Le premier jeu de fonctions d'os.path analyse des chaînes de caractères représentant des noms de fichiers (indépendamment de leur existance).
Cette analyse dépend des variables suivantes :
La méthode split() sépare le chemin en deux éléments (par rapport à os.sep = '/') : le dernier élément, et le reste. Le retour est un couple :
>>> import os.path
>>> for path in [ '/one/two/three',
... '/one/two/three/',
... '/',
... '.',
... '']:
... print '"s"' % (path, os.path.split(path))
"/one/two/three" : "('/one/two', 'three')"
"/one/two/three/" : "('/one/two/three', '')"
"/" : "('/', '')"
"." : "('', '.')"
"" : "(, )"
La méthode basename() retourne la deuxième valeur de retour de split(), à savoir la partie la plus à droite du chemin :
>>> import os.path
>>> for path in [ '/one/two/three',
... '/one/two/three/',
... '/',
... '.',
... '']:
... print '"s"' % (path, os.path.basename(path))
"/one/two/three" : "three"
"/one/two/three/" : ""
"/" : ""
"." : "."
"" : ""
La méthode dirname() retourne la première valeur de retour de split(), à savoir tout ce qui n'est pas la partie la plus à droite du chemin :
>>> import os.path
>>> for path in [ '/one/two/three',
... '/one/two/three/',
... '/',
... '.',
... '']:
... print '"s"' % (path, os.path.dirname(path))
"/one/two/three" : "/one/two"
"/one/two/three/" : "/one/two/three"
"/" : "/"
"." : ""
"" : ""
La méthode splitext() fonctionne comme split(), sauf que la séparation ne se fait pas sur le dernier os.sep ('/'), mais sur os.extsep (le séparateur de l'extension '.')
>>> import os.path
>>> for path in [ 'filename.txt', 'filename', '/path/to/filename.txt', '/', '' ]:
... print '" path, os.path.splitext(path)
"filename.txt" : ('filename', '.txt')
"filename" : ('filename', '')
"/path/to/filename.txt" : ('/path/to/filename', '.txt')
"/" : ('/', '')
"" : (, )
commonprefix() reçoit une liste de chemins pour argument, et retourne le préfixe commun à tout ces chemins.
>>> import os.path >>> paths = ['/one/two/three/four', ... '/one/two/threefold', ... '/one/two/three/', ... ] >>> print os.path.commonprefix(paths) /one/two/three
On constate que, dans cet exemple, le préfixe commun n'est pas '/one/two', mais '/one/two/three'...
La méthode join() permet de combiner différents chemins :
>>> import os.path >>> for parts in [ ('one', 'two', 'three'), ... ('/', 'one', 'two', 'three'), ... ('/one', '/two', '/three'), ... ]: ... print parts, ':', os.path.join(*parts) ('one', 'two', 'three') : one/two/three ('/', 'one', 'two', 'three') : /one/two/three ('/one', '/two', '/three') : /three
On peut travailler avec des chemins comprenant des "variables" pouvant être automatiquement étendues. Par exemple, expanduser() permet de convertir le tilde (~) en '/home/guyeux' :
>>> import os.path >>> os.path.expanduser('~') '/home/guyeux' >>> os.path.expanduser('~guyeux') '/home/guyeux' >>> os.path.expanduser('~mysql') '/var/lib/mysql'
La méthode expandvars() est plus générale que expanduser : il étend toute variable d'environnement présente dans le chemin :
>>> import os.path >>> import os >>> os.environ['MYVAR'] = 'VALUE' >>> print os.path.expandvars('/path/to/$MYVAR') /path/to/VALUE
Certains chemins, assemblés avec join() ou de toute autre manière, doivent être normalisés :
>>> import os.path >>> for path in [ 'one//two//three', ... 'one/./two/./three', ... 'one/../one/two/three', ... ]: ... print path, ':', os.path.normpath(path) one//two//three : one/two/three one/./two/./three : one/two/three one/../one/two/three : one/two/three
Pour convertir un chemin relatif en un chemin absolu, on utilise abspath().
>>> import os.path
>>> for path in [ '.', '..', './one/two/three', '../one/two/three']:
... print '"s"' % (path, os.path.abspath(path))
"." : "/Users/dhellmann/Documents/PyMOTW/in_progress/ospath"
".." : "/Users/dhellmann/Documents/PyMOTW/in_progress"
"./one/two/three" : "/Users/dhellmann/Documents/PyMOTW/in_progress/ospath/one/two/three"
"../one/two/three" : "/Users/dhellmann/Documents/PyMOTW/in_progress/one/two/three"
os.path contient des fonctions pour récupérer des informations sur le fichier considéré, d'une manière plus pratique qu'en utilisant os.stat() :
>>> import os.path >>> import time >>> print 'File :', __file__ >>> print 'Access time :', time.ctime(os.path.getatime(__file__)) >>> print 'Modified time:', time.ctime(os.path.getmtime(__file__)) >>> print 'Change time :', time.ctime(os.path.getctime(__file__)) >>> print 'Size :', os.path.getsize(__file__) File : /Users/dhellmann/Documents/PyMOTW/in_progress/ospath/ospath_properties.py Access time : Sun Jan 27 15:40:20 2008 Modified time: Sun Jan 27 15:39:06 2008 Change time : Sun Jan 27 15:39:06 2008 Size : 478
On souhaite parfois savoir si le chemin considéré fait référence à un répertoire ou à un fichier.
De même, si notre plateforme le permet, on peut souhaiter savoir si le chemin fait référence à un lien symbolique, voire à un point de montage.
On peut encore vouloir tester si le chemin existe ou non...
>>> import os.path >>> for file in [ __file__, os.path.dirname(__file__), '/', './broken_link']: ... print 'File :', file ... print 'Absolute :', os.path.isabs(file) ... print 'Is File? :', os.path.isfile(file) ... print 'Is Dir? :', os.path.isdir(file) ... print 'Is Link? :', os.path.islink(file) ... print 'Mountpoint? :', os.path.ismount(file) ... print 'Exists? :', os.path.exists(file) ... print 'Link Exists?:', os.path.lexists(file) File : /Users/dhellmann/Documents/PyMOTW/in_progress/ospath/ospath_tests.py Absolute : True Is File? : True Is Dir? : False Is Link? : False Mountpoint? : False Exists? : True Link Exists?: True
os.path.walk() traverse tous les répertoires dans une arborescence, et appelle une fonction permettant d'analyser le nom des repertoires et les noms de leurs contenus.
>>> 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 ... if '.svn' in names: ... names.remove('.svn') ... print >>> os.path.walk('..', visit, '(User data)') .. (User data) .svn/ ospath/ ../ospath (User data) .svn/ __init__.py ospath_abspath.py ospath_basename.py ospath_commonprefix.py ospath_dirname.py ospath_expanduser.py ospath_expandvars.py ospath_join.py ospath_normpath.py ospath_properties.py ospath_split.py ospath_splitext.py ospath_tests.py ospath_walk.py