El autor seleccionó el COVID-19 Relief Fund para que reciba una donación como parte del programa Write for DOnations.
Python 3 incluye el módulo pathlib
para manipular rutas de sistemas de archivos de forma agnóstica en cualquier sistema operativo. El módulo pathlib
es similar al os.path
, pero pathlib
ofrece una interfaz de nivel más alto, y, a menudo, más conveniente, que os.path
.
Podemos identificar archivos en una computadora con rutas jerárquicas. Por ejemplo, podemos identificar el archivo wave.txt
en una computadora con esta ruta: /Users/sammy/ocean/wave.txt
. Cada sistema operativo tiene una manera ligeramente distinta de representar rutas. Windows puede representar la ruta al archivo wave.txt
de la siguiente manera: C:\Users\sammy\ocean\wave.txt
.
El módulo pathlib
le puede resultar útil si desea a crear o mover archivos en el sistema de archivos de su programa de Python, enumerar los archivos del sistema de archivos que coincidan con una extensión o un patrón determinado o crear rutas de archivos apropiadas para el sistema operativo basadas en colecciones de cadenas sin procesar. Si bien es posible usar otras herramientas (como el módulo os.path
) para realizar muchas de estas tareas, el módulo pathlib
le permite realizar estas operaciones con un alto grado de legibilidad y una cantidad de código mínima.
En este tutorial, revisaremos algunas de las maneras de usar el módulo pathlib
para representar y manipular las rutas de los sistemas de archivos.
Para sacar el máximo provecho de este tutorial, se recomienda tener cierta familiaridad con la programación en Python 3. Puede consultar estos tutoriales para obtener la información de fondo necesaria:
Path
El módulo pathlib
proporciona varias clases, pero una de las más importantes es la clase Path
. Las instancias de la clase Path
representan una ruta a un archivo o un directorio en el sistema de archivos de nuestra computadora.
Por ejemplo, el siguiente código inicia una instancia Path
que representa una parte de la ruta a un archivo wave.txt
:
from pathlib import Path
wave = Path("ocean", "wave.txt")
print(wave)
Si ejecutamos este código, obtendremos un resultado como el siguiente:
Outputocean/wave.txt
from pathlib import Path
permite que la clase Path
esté disponible en nuestro programa. Luego, Path("ocean", "wave.txt")
crea una instancia de Path
nueva. El resultado muestra que Python ha añadido el separador /
adecuado del sistema operativo entre los dos componentes de la ruta que le proporcionamos: "ocean"
y "wave.txt"
.
Nota: Sus resultados pueden diferir ligeramente de los que se muestran como ejemplo en este tutorial en función del sistema operativo que utilice. Si utiliza Windows, por ejemplo, su resultado para este primer ejemplo puede tener este aspecto: ocean\wave.txt
.
Actualmente, el objeto Path
asignado a la variable wave
contiene una ruta relativa. En otras palabras, ocean/wave.txt
puede existir en varias ubicaciones de nuestro sistema de archivos. Por ejemplo, puede estar presente en /Users/user_1/ocean/wave.txt
o /Users/user_2/research/ocean/wave.txt
, pero no especificamos exactamente a cuál nos estamos refiriendo. Por el contrario, una ruta absoluta se refiere inequívocamente a una ubicación en el sistema de archivos.
Puede usar Path.home()
para obtener la ruta absoluta al directorio principal del usuario actual:
home = Path.home()
wave_absolute = Path(home, "ocean", "wave.txt")
print(home)
print(wave_absolute)
Si ejecutamos este código, obtendremos un resultado similar al siguiente:
Output/Users/sammy
/Users/sammy/ocean/wave.txt
Nota: Como se mencionó anteriormente, su resultado variará dependiendo de su sistema operativo. Por supuesto, su directorio principal también será distinto de /Users/sammy
.
Path.home()
devuelve una instancia Path
con una ruta absoluta al directorio principal del usuario actual. Luego, pasamos esta instancia de Path
y las cadenas "ocean"
y "wave.txt"
a otro constructor de Path
para crear una ruta absoluta al archivo wave.txt
. El resultado indica que la primera línea es el directorio principal y la segunda, el directorio principal más ocean/wave.txt
.
Este ejemplo también ilustra una característica importante de la clase Path
: el constructor Path
acepta tanto cadenas como objetos preexistentes de Path
.
Analicemos con mayor detalle cómo es que el constructor Path
admite tanto cadenas como de objetos de Path
:
shark = Path(Path.home(), "ocean", "animals", Path("fish", "shark.txt"))
print(shark)
Si ejecutamos este código de Python, obtendremos un resultado similar al siguiente:
Output/Users/sammy/ocean/animals/fish/shark.txt
shark
es un Path
a un archivo que construimos usando tanto objetos Path
(Path.home()
y Path("fish", "shark.txt")
) como cadenas ("ocean"
y "animals"
). El constructor Path
gestiona de forma inteligente ambos tipos de objetos y los une de forma correcta usando el separador correspondiente del sistema operativo, en este caso: /
.
Ahora que hemos aprendido a crear instancias de Path
, vamos a repasar cómo puede usar esas instancias para acceder a información sobre un archivo.
Podemos usar los atributos name
y suffix
para acceder a los nombres y los sufijos de archivos:
wave = Path("ocean", "wave.txt")
print(wave)
print(wave.name)
print(wave.suffix)
Al ejecutar este código, obtendremos un resultado similar al siguiente:
Output/Users/sammy/ocean/wave.txt
wave.txt
.txt
Este resultado indica que el nombre del archivo al final de nuestra ruta es wave.txt
y el sufijo de ese archivo es .txt
.
Las instancias de Path
también ofrecen la función with_name
, que le permite crear de forma sencilla un objeto Path
nuevo con un nombre distinto:
wave = Path("ocean", "wave.txt")
tides = wave.with_name("tides.txt")
print(wave)
print(tides)
Si ejecutamos este código, obtendremos un resultado similar al siguiente:
ocean/wave.txt
ocean/tides.txt
El código, primero, construye una instancia Path
que apunta a un archivo llamado wave.txt
. Luego, invoca el método with_name
en wave
para devolver una segunda instancia Path
que apunta a un archivo nuevo denominado tides.txt
. La parte del directorio ocean/
de la ruta permanece intacta, por lo tanto, la ruta final queda establecida como ocean/tides.txt
A veces, resulta útil acceder a directorios que contienen una ruta determinada. Consideremos un ejemplo:
shark = Path("ocean", "animals", "fish", "shark.txt")
print(shark)
print(shark.parent)
Si ejecutamos este código, obtendremos un resultado similar al siguiente:
Outputocean/animals/fish/shark.txt
ocean/animals/fish
El atributo parent
en una instancia de Path
devuelve el antecesor más inmediato de una ruta de archivos determinada. En este caso, devuelve el directorio que contiene el archivo shark.txt
: ocean/animals/fish
.
Podemos acceder al atributo parent
varias veces seguidas para recorrer el árbol de ancestros de un archivo determinado:
shark = Path("ocean", "animals", "fish", "shark.txt")
print(shark)
print(shark.parent.parent)
Si ejecutamos este código, obtendremos el siguiente resultado:
Outputocean/animals/fish/shark.txt
ocean/animals
El resultado es similar al anterior, pero, ahora, hemos llegado a un nivel más alto al acceder a .parent
por segunda vez. El directorio ocean/animals
se encuentra dos directorios por encima de shark.txt
.
También es posible usar la clase Path
para enumerar archivos usando el método glob
.
Imaginemos que tenemos una estructura de directorios similar a la siguiente:
└── ocean
├── animals
│ └── fish
│ └── shark.txt
├── tides.txt
└── wave.txt
Un directorio ocean
que contiene los archivos tides.txt
y wave.txt
. Tenemos un archivo denominado shark.txt
anidado en el directorio ocean
, un directorio animals
y otro fish
: ocean/animals/fish
.
Para enumerar todos los archivos .txt
del directorio ocean
, podríamos escribir lo siguiente:
for txt_path in Path("ocean").glob("*.txt"):
print(txt_path)
Este código tendría un resultado similar al siguiente:
Outputocean/wave.txt
ocean/tides.txt
El patrón glob __"*.txt"
busca todos los archivos que terminan en .txt
. Como el código del ejemplo ejecuta ese glob en el directorio ocean
, devuelve los dos archivos .txt
del directorio ocean
: wave.txt
y tides.txt
.
Nota: Para duplicar los resultados que se muestran en este ejemplo, copie la estructura de directorios que se ilustra aquí en su computadora.
También podemos usar el método glob
de manera recursiva. Para enumerar todos los archivos .txt
del directorio ocean
y todos sus subdirectorios, podemos escribir lo siguiente:
for txt_path in Path("ocean").glob("**/*.txt"):
print(txt_path)
Al ejecutar este código, obtendríamos un resultado similar al siguiente:
Outputocean/wave.txt
ocean/tides.txt
ocean/animals/fish/shark.txt
La sección **
del patrón glob coincidirá con este directorio y todos sus subdirectorios de manera recursiva. Por tanto, no solo tenemos los archivos wave.txt
y tides.txt
en el resultado, sino que también recibimos el archivo shark.txt
que estaba anidado en ocean/animals/fish
.
Podemos usar el método Path.relative_to
para calcular rutas relacionadas entre sí. El método relative_to
es útil cuando, por ejemplo, se desea recuperar una porción de una ruta de archivos larga.
Analice el siguiente código:
shark = Path("ocean", "animals", "fish", "shark.txt")
below_ocean = shark.relative_to(Path("ocean"))
below_animals = shark.relative_to(Path("ocean", "animals"))
print(shark)
print(below_ocean)
print(below_animals)
Si ejecutamos este código, obtendremos un resultado similar al siguiente:
Outputocean/animals/fish/shark.txt
animals/fish/shark.txt
fish/shark.txt
El método relative_to
devuelve un nuevo objeto Path
relacionado con el argumento determinado. En nuestro ejemplo, calculamos el Path
a shark.txt
en relación con el directorio ocean
y, luego, en relación con los directorios ocean
y animals
.
Si relative_to
no puede calcular una respuesta porque le indicamos una ruta no relacionada, presenta un ValueError
:
shark = Path("ocean", "animals", "fish", "shark.txt")
shark.relative_to(Path("unrelated", "path"))
Obtendremos una excepción ValueError
generada a partir de este código que será similar a la siguiente:
OutputTraceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/local/lib/Python3.8/pathlib.py", line 899, in relative_to
raise ValueError("{!r} does not start with {!r}"
ValueError: 'ocean/animals/fish/shark.txt' does not start with 'unrelated/path'
unrelated/path
no forma parte de ocean/animals/fish/shark.txt
, por lo tanto, Python no puede calcular una ruta relativa.
El módulo pathlib
es un componente importante de la biblioteca estándar de Python que nos permite manipular rutas de sistemas de archivos de forma rápida en cualquier sistema operativo. En este tutorial, ha aprendido a usar algunas de las herramientas clave de pathlib
para acceder a los atributos de archivos, enumerar archivos con patrones glob y desplazarse por archivos y directorios principales.
El módulo pathlib
expone clases y utilidades adicionales que no abarcamos en este tutorial. Ahora que tiene una referencia, puede usar la documentación del módulo pathlib
para obtener más información sobre otras clases y utilidades disponibles.
Si está interesado en utilizar otras bibliotecas de Python, consulte los siguientes tutoriales:
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!