Acceso a un directorio
Sintetizo en esta entrada los diferentes modos de acceso a directorios y a su contenido que he ido conociendo mientras buscaba solucionar algunos problemas que implicaban el manejo de directorios. Puede que no sean los únicos disponibles, así que si encuentro alguno más realizaré las modificaciones que correspondan en esta entrada.
Lo que pretendo con ella es exponer los procedimientos más simples y cómo se concretan mediante código; por ello sólo sirven como punto de partida para el logro de objetivos de mayor complejidad o más específicos que lo que implica este planteamiento genérico.
Además algunos procedimientos que aquí se explica es posible que ya hayan sido expuestos en otras entrada, o que se vuelvan a plantear en entradas posteriores a esta. En parte es inevitable dado el carácter básico y genérico que tienen estos procedimiento. Espero, no obstante, que este esfuerzo de síntesis y por facilitar el acceso a código básico compense el trabajo de hacer esta entrada... y de leerla.
Para acceder a los directorios y a contenido necesitamos importar (al menos por ahora) dos bibliotecas básicas de Python, las mismas que he comentado en el inicio de esta subsección: la [biblioteca os] y la [biblioteca pathlib]. Es por ello que debemos importarlas al inicio del script:
También necesitamos identificar la ruta absoluta del directorio con el que deseamos trabajar, en nuestro caso...
directorio = 'D:/BasesDatosTest'
A partir de aquí expongo cada una de las opciones, empezando por la más básica, la que proporciona la función os.listdir()
lista_dir1 = os.listdir(directorio)
print(lista_dir1)
for elem in lista_dir1:
print(elem)
La primera respuesta que obtenemos (print(lista_dir1)) aplicar esa función (lista_dir1 = os.listdir(directorio)) es un lista de los elementos presentes en el directorio, tanto documentos como subdirectorios...
['ALBOR_emle.pdf', 'BasesDatosPROLECR', 'EXPEDIENTES', 'ITPA-CA', 'TEA_BASIIa.pdf', 'TEA_BASIIb.pdf', 'TEA_InfoDP3.pdf', 'TEA_Matrices.pdf', 'TEA_MatricesManual.pdf', 'WISC_BaseDatos']
... pero si queremos observarla de forma más accesible, podemos utilizar la segunda fórmula, mediante un ciclo que recorre la lista: (for elem in lista_dir1:) -> (print(elem)), nos devuelve...
ALBOR_emle.pdf
BasesDatosPROLECR
EXPEDIENTES
ITPA-CA
TEA_BASIIa.pdf
TEA_BASIIb.pdf
TEA_InfoDP3.pdf
TEA_Matrices.pdf
TEA_MatricesManual.pdf
WISC_BaseDatos
La segunda forma de listar los elementos que componen un directorio pasa por usar la función os.walk(), y presenta la siguiente sintaxis...
for carpeta,subcarpeta, archivo in os.walk(directorio):
print(carpeta)
print(subcarpeta)
print(archivo)
... que devuelve un complejo listado de listas, que a simple vista parece complicado descifrar, pero que con paciencia y trabajo podemos convertir en un sistema funcional de acceder a cualquiera de los diferentes niveles o nodos que contenga y estructure el directorio principal. Aquí únicamente hemos los visualizado.
D:/BasesDatosTest
['BasesDatosPROLECR', 'EXPEDIENTES', 'ITPA-CA', 'WISC_BaseDatos']
['ALBOR_emle.pdf', 'TEA_BASIIa.pdf', 'TEA_BASIIb.pdf', 'TEA_InfoDP3.pdf', 'TEA_Matrices.pdf', 'TEA_MatricesManual.pdf']
D:/BasesDatosTest\BasesDatosPROLECR
['Prolec_CtCo', 'prolec_r_Completo']
['PROLECComprensionTextos.fmp12', 'PROLECComprensionTextos2.fmp12', 'PROLECComprensionTextos2b.fmp12', 'PROLECComprensionTextual.fmp12', 'PROLECEstructurasGramaticales.fmp12', 'PROLECEstructurasGramaticales2.fmp12']
Este ejemplo es una mínima muestra del conjunto, pero permite observar cómo se han identificado:
- La estructura y composición del directorio principal (print(carpeta)), su ruta (D:/BasesDatosTest) y las dos colecciones de componentes que contiene:
- Los subdirectorios (['BasesDatosPROLECR', 'EXPEDIENTES', 'ITPA-CA', 'WISC_BaseDatos'])
- Y los archivos que se encuentran en el directorio principal
['ALBOR_emle.pdf', 'TEA_BASIIa.pdf', 'TEA_BASIIb.pdf', 'TEA_InfoDP3.pdf', 'TEA_Matrices.pdf', 'TEA_MatricesManual.pdf']
- Y el segundo nivel, sólo el subdirectorio D:/BasesDatosTest\BasesDatosPROLECR y una mínima parte de lo que contiene...
- Sus dos subdirectorios secundarios (['Prolec_CtCo', 'prolec_r_Completo'])
- Y la lista de los documentos que se encuentran ubicados directamente en ese mismo nivel
['PROLECComprensionTextos.fmp12', 'PROLECComprensionTextos2.fmp12', 'PROLECComprensionTextos2b.fmp12', 'PROLECComprensionTextual.fmp12', 'PROLECEstructurasGramaticales.fmp12', 'PROLECEstructurasGramaticales2.fmp12']
Esto nos da una idea de cómo funciona esta función, de la complejidad de la información que aporta y del potencial que tiene su uso en proyecto que requieran, por ejemplo, conocer el contenido y la estructura de directorios complejos.
El tercer modo de obtener información sobre la composición de un directorio implica el uso de la función os.scandir()...
with os.scandir(directorio) as archivos:
for archivo in archivos:
print(archivo.name)
... y que, como vemos, requiere el uso de la estructura with (with os.scandir(directorio) as archivos:), a partir de la cual accedemos (aquí sólo con la función de mostrar el contenido del directorio-> print(archivo.name)) mediante un ciclo for que recorre el iterable que resulta de with (archivos -> for archivo in archivos:), gracias al cual obtenemos un resultado...
ALBOR_emle.pdf
BasesDatosPROLECR
EXPEDIENTES
ITPA-CA
TEA_BASIIa.pdf
TEA_BASIIb.pdf
TEA_InfoDP3.pdf
TEA_Matrices.pdf
TEA_MatricesManual.pdf
WISC_BaseDatos
... aparentemente idéntico al que obtenemos con os.listdir() cuando aplicamos un bucle, pero que en realidad contiene otras funcionalidades, ya que con os.scandir() estamos trabajando con objetos, no con cadenas de texto. Es testigo de ello el modo en que se formula la instrucción de impresión (print(archivo.name)), diferente al modo en que se formula desde os.listdir (print(elem))
De hecho os.scandir() permite obtener respuestas similares a las que proporciona la cuarta y última forma de acceder al directorio. Esta es la única de las vistas que emplea la biblioteca pathlib, concretamente su módulo Path. Y también permite obtener un objeto, con las funcionalidades que esto conlleva, y que ahora no podemos apreciar por lo limitado de nuestro objetivo:
archivos = Path(directorio)
for archivo in archivos.iterdir():
print(archivo.name)
El interés de esta opción no es tanto el resultado (que es el mismo que la anterior: un listado de elementos (subdirectorios y archivos) como la simplicidad con la que se formula. Por ejemplo, ahora no es necesario usar la estructura with ya que el uso de la función (archivos = Path(directorio)) posibilita identificar a la estructura de contenidos que genera como iterable (for archivo in archivos.iterdir():) en la propia formulación del for.