El módulo pathlib disponible desde Python 3.4 consta de clases que permiten representar rutas de archivos y directorios de un sistema de ficheros con la semántica adecuada para distintos sistemas operativos.
Las clases cuentan con métodos que facilitan una amplia variedad de operaciones con directorios, archivos y enlaces simbólicos; que antes eran posibles, la mayoría, recurriendo a funciones y clases de varios módulos (como os, glob, shutil y fileinput). Lo que se ha pretendido con pathlib es concentrar en un módulo las operaciones más comunes teniendo en cuenta la experiencia de los desarrolladores.
Dentro de las operaciones contempladas las hay para explorar el sistema de ficheros, comprobar la existencia de rutas; recorrer los archivos y subdirectorios de un directorio filtrando los objetos mediante el uso de patrones; obtener información de los objetos (tamaño, permisos, propietarios, etc.); crear, renombrar y borrar archivos y enlaces simbólicos; crear y borrar directorios; obtener rutas del sistema en varios formatos (Posix y URI), principalmente.
Las clases cuentan con métodos que facilitan una amplia variedad de operaciones con directorios, archivos y enlaces simbólicos; que antes eran posibles, la mayoría, recurriendo a funciones y clases de varios módulos (como os, glob, shutil y fileinput). Lo que se ha pretendido con pathlib es concentrar en un módulo las operaciones más comunes teniendo en cuenta la experiencia de los desarrolladores.
Dentro de las operaciones contempladas las hay para explorar el sistema de ficheros, comprobar la existencia de rutas; recorrer los archivos y subdirectorios de un directorio filtrando los objetos mediante el uso de patrones; obtener información de los objetos (tamaño, permisos, propietarios, etc.); crear, renombrar y borrar archivos y enlaces simbólicos; crear y borrar directorios; obtener rutas del sistema en varios formatos (Posix y URI), principalmente.
Rutas puras y concretas
Las clases de pathlib se dividen en dos grupos en función a los tipos de rutas orientadas a objetos que manejan: puras y concretas. La diferencia entre ambos tipos de clases está en que las clases para rutas puras proporcionan métodos que en realidad no acceden al sistema de ficheros y las de rutas concretas, sí.
Las rutas son inmutables y por ser únicas en cada sistema de archivos se les pueden aplicar funciones hash. Las rutas de un mismo sistema se pueden comparar y ordenar de acuerdo a la semántica empleada en cada sistema.
Cualquier ruta se representa como una cadena adaptada a las rutas propias de cada sistema de archivos y, lógicamente, se podrán utilizar con cualquier función que opere con rutas en este mismo formato.
Hay tres formas de instanciar objetos de rutas puras:
A continuación, se declaran varias rutas puras y se muestran varios ejemplos que ilustran el uso de sus métodos:
Las rutas son inmutables y por ser únicas en cada sistema de archivos se les pueden aplicar funciones hash. Las rutas de un mismo sistema se pueden comparar y ordenar de acuerdo a la semántica empleada en cada sistema.
Cualquier ruta se representa como una cadena adaptada a las rutas propias de cada sistema de archivos y, lógicamente, se podrán utilizar con cualquier función que opere con rutas en este mismo formato.
Hay tres formas de instanciar objetos de rutas puras:
- class pathlib.PurePath(*pathsegments): clase genérica que crea una instancia de ruta en función del sistema operativo: puede ser PurePosixPath o un PureWindowsPath.
- class pathlib.PurePosixPath(*pathsegments): subclase que crea una instancia de ruta para sistemas de ficheros no Windows.
- class pathlib.PureWindowsPath(*pathsegments): subclase que crea una instancia de ruta para sistemas de ficheros Windows.
A continuación, se declaran varias rutas puras y se muestran varios ejemplos que ilustran el uso de sus métodos:
import os from pathlib import PurePath, PurePosixPath, PureWindowsPath # Declarar rutas puras ruta1 = PurePath('home/usuario') ruta2 = PurePath('c:\\windows') ruta3 = PurePosixPath('home/Usuario') ruta4 = PureWindowsPath('C:\\WINDOWS') # Imprimir las rutas print(ruta1) # home/usuario print(ruta2) # c:\windows print(ruta3) # home/Usuario print(ruta4) # C:\WINDOWS # Las rutas son cadenas de un tipo especial print(type(ruta1)) #print(type(ruta2)) # print(type(ruta3)) # print(type(ruta4)) # # Las rutas se pueden comparar ... print(ruta1 == ruta3) # False print(ruta2 == ruta4) # True (en Windows) print(ruta2 in [ruta4]) # True (en Windows) print(PureWindowsPath('c:\\windows') > ruta4) # False if os.name != 'posix': print(ruta2 > ruta4) # False (en Win); Error (en No Win) # Una ruta se representa como una cadena adaptada a # las rutas propias de cada sistema de archivos ruta5 = PurePath('/var/www/index.html') ruta6 = PureWindowsPath('c:/Program Files') print(ruta5) # /var/www/index.html print(ruta6) # c:\Program Files # Obtener por separado en una tupla todas las partes de una ruta print(ruta5.parts) # ('/', 'var', 'www', 'index.html') print(ruta6.parts) # ('c:\\', 'Program Files') # Obtener la unidad (si existe) de una ruta print(ruta5.drive) # '' print(ruta6.drive) # 'c:' # Obtener la raíz de una ruta. Válido para rutas UNC print(ruta5.root) # '/' print(ruta6.root) # '\' # Obtener la raíz y la ruta ¡de una vez! print(ruta5.anchor) # '/' print(ruta6.anchor) # 'c:\' # Obtener los ancestros de una ruta print(ruta5.parents) # print(len(ruta5.parents)) # Número de ancestros: 3 print(ruta5.parents[0]) # /var/www print(ruta5.parents[1]) # /var print(ruta5.parents[2]) # / # Obtener el ancestro ineidato o padre de una ruta print(ruta5.parent) # /var/www print(ruta6.parent) # c:\ # Obtener nombre y extensión/es de archivos print(ruta5.name) # index.html print(ruta5.suffix) # .html print(ruta5.suffixes) # ['.html'] print(ruta5.stem) # index # Obtener rutas en formato POSIX y URI print(ruta6.as_posix()) # c:/Program Files print(ruta6.as_uri()) # file:///c:/Program%20Files # Obtener si una ruta es absoluta: si tiene raíz o unidad print(ruta5.is_absolute()) # True print(ruta6.is_absolute()) # True # Combinar rutas print(ruta6.joinpath('Lupa')) # c:\Program Files\Lupa print(ruta6) # c:\Program Files # Comprobar si un patrón existe en una ruta print(ruta5.match('*.html')) # True print(ruta5.match('var/*.html')) # False # Obtener la ruta relativa (si es posible) print(ruta5.relative_to('/var')) # www/index.html print(ruta5.relative_to('/var/www')) # index.html # A partir de una ruta obtener otra ruta cambiando # nombre completo de archivo o extensión (si es posible) print(ruta5.with_name('imagen.jpg')) # /var/www/imagen.jpg print(ruta5.with_suffix('.htm')) # /var/www/index.htm
Por otra parte, los objetos de ruta concreta pertenecen a subclases de las clases de rutas puras. Estas subclases además de ofrecer las operaciones proporcionadas por las clases de las que descienden cuentan con métodos para instancias de rutas que hacen llamadas al sistema. Hay tres formas de instanciar estos objetos:
A continuación se declaran varias rutas concretas y se ofrecen varios ejemplos que muestran el uso de sus métodos:
- class pathlib.Path(*pathsegments): es una subclase de la clase PurePath que crea una instancia de ruta concreta en función del sistema operativo: puede ser PosixPath o WindowsPath.
- class pathlib.PosixPath(*pathsegments): es una subclase de la clase PurePosixPath que crea una instacia de ruta concreta para sistemas de ficheros no Windows.
- class pathlib.WindowsPath(*pathsegments): es una subclase de la clase PureWindowsPath que crea una instancia de ruta concreta para sistemas de ficheros Windows.
A continuación se declaran varias rutas concretas y se ofrecen varios ejemplos que muestran el uso de sus métodos:
from pathlib import Path, PosixPath, WindowsPath # Declarar rutas concretas ruta1 = Path('home/usuario') ruta2 = Path('c:\\windows') ruta3 = PosixPath('home/Usuario') ruta4 = WindowsPath('C:\\WINDOWS') # Error en Linux # Imprimir las rutas print(ruta1) # home/usuario print(ruta2) # c:\windows print(ruta3) # home/Usuario print(ruta4) # C:\WINDOWS # Las rutas son cadenas de un tipo especial ... print(type(ruta1)) #print(type(ruta2)) # print(type(ruta3)) # print(type(ruta4)) # # Obtener ruta del directorio actual de trabajo print(Path.cwd()) # /home/usuario/Directorio # Obtener la ruta del directorio de usuario actual print(Path.home()) # /home/usuario # Obtener información del directio o del archivo # Obtener tamaño en bytes print(Path('/etc/os-release').stat().st_size) # 386 # Obtener tiempo de modificación (expresado en segundos) print(Path('/etc/os-release').stat().st_mtime) # 1534722298.0 # Para enlaces simbólicos: lstat() # Cambiar los atributos y/o permisos del directorio o del archivo Path('/home/usu1/imagen1.png').chmod(0o666) # Para enlaces simbólicos: lchmod() # Comprobar si existe el archivo o directorio print(Path('/etc/os-release').exists()) # True # Expandir la ruta añadiendo la ruta 'home' del usuario actual print(Path('~/bashrc').expanduser()) # /home/usuario/bashrc # Obtener de la ruta una lista con los archivos del patrón archivos = Path('/home/usu1/Descargas').glob('*.pdf') for archivo in archivos: print(archivo) # Otros patrones: # '*/*.pdf' Obtener del directorio con 1 nivel de profundidad # '**/*.pdf' Obtener del directorio actual y sus subdirectorios # El patrón '**/*.pdf' es equivalente a rglob('*.pdf') # Obtener nombre del grupo propietario print(Path('/etc/os-release').group()) # root # Conocer si una ruta es un directorio o un enlace simbólico # que apunta a un directorio existente print(Path('/etc/os-release').is_dir()) # False # Conocer si una ruta es un fichero o un enlace simbólico # que apunta a un fichero existente print(Path('/etc/os-release').is_file()) # True # Conocer si una ruta es un enlace simbólico print(Path('/etc/resolv.conf').is_symlink()) # True # Conocer si la ruta es un punto de montaje. # No implementado para windows. Nuevo en Python 3.7 print(Path('/media/usuario').is_mount()) # True # Obtener iterador con objetos contenidos en un directorio for elemento in Path('/home/usu1/Descargas').iterdir(): print(elemento) # Lista ficheros y directorios # Crear un directorio (si no existe) Path('/home/u1/bd').mkdir(mode=0o777, parents=False, exist_ok=True) # Si parents=True creará los directorios padres que falten # en el camino # Si exist_ok=True y el directorio a crear existe se # omitirá mensaje de error # Abrir un archivo para leer y/o escribir with Path('/etc/os-release').open(mode='r') as archivo: for linea in archivo: print(linea.strip()) # Leer y escribir de/en un archivo de texto archivo = Path('secreto.txt') archivo.write_text('Este archivo guarda un gran secreto') print(archivo.read_text()) # Leer y escribir de/en un archivo en formato binario archivo = Path('secreto.dat') archivo.write_bytes(b'Este archivo guarda un gran secreto') print(archivo.read_bytes()) # Conocer el propietario de un archivo print(Path('/etc/resolv.conf').owner()) # root # Renombrar un archivo o un directorio Path('/home/usu1/imagen1.png').rename('/home/usu1/imagen2.png') # En Unix si se trata de un archivo existeste será reemplazado. # Renombrar un archivo o un directorio. Path('/home/usu1/imagen2.png').replace('/home/usu1/imagen1.png') # Si existe archivo o directorio será reemplezado # Convertir una ruta en absoluta print(Path('/etc/resolv.conf').resolve()) # /run/resolvconf/resolv.conf print(Path('..').resolve()) # /home/usuario/Local # Borrar un directorio vacío dir1 = Path('/home/usu1/temp-1') if dir1.exists(): dir1.rmdir() # Conocer si hay coincidencia en dos rutas documentos = '/home/usu1/.bashrc' print(Path('/home/usu1/.bashrc').samefile(documentos)) # True # Crear un enlace simbólico Path('MiEnlace').symlink_to('imagen.png') # Borrar un archivo o un enlace simbólico Path('imagen.png').unlink()
Relacionado:
Ir al índice del tutorial de Python