Mostrando entradas con la etiqueta Directorios. Mostrar todas las entradas
Mostrando entradas con la etiqueta Directorios. Mostrar todas las entradas

viernes, 7 de noviembre de 2025

Python. Directorios


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:

import os
from pathlib import Path

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.  

Python. Directorios.


Módulo pathlib




El módulo pathlib es una biblioteca estándar que permite trabajar con rutas desde un planteamiento de programación orientada a objetos (POO) compatible con diferentes sistemas operativos. Se presenta como sustituto del módulo os.path y permite crear y manipular directorios y archivos.


Este módulo, que puedes estudiar con detalle desde [este enlace] presenta las siguientes funcionalidades:

  • Trabaja dentro del paradigma de la POO, por lo que utiliza objetos Path para representar las rutas en lugar de cadenas de texto, como es el caso del módulo os.path. Esto permite utilizar métodos y atributos para manejarlas.
  • Es independiente de la plataforma, por lo que maneja automáticamente los diferentes separadores de ruta (\ en Windows y / en Linux/macOS), facilitando que el código funcione correctamente con independencia del sistema operativo.
  • Permite realizar diversas operaciones directamente sobre los directorios (objeto Path): crear, eliminar, renombrar o mover archivos y directorios.
  • Facilita el acceso a componentes de la ruta: nombre del archivo (.name), nombre sin extensión (.stem) o sólo la extensión(.suffix).
  • Posibilita saber si una ruta existe, y si se trata de un archivo o un directorio.
  • Permite recorrer directorios y subdirectorios, filtrando los objetos mediante patrones.







lunes, 16 de junio de 2025

Python. Directorios


Contenido de un directorio




En este momento necesito saber cuáles y cuantos son los componentes de un directorio. Para ello recurriré de nuevo al módulo os de Python.


Supongo que deseo conocer el contenido de un determinado directorio cuya dirección localizo mediante la funcionalidad Propiedades de Documentos del sistema, que me devuelve D:/PROGRAMACION/OOoBasic/Documentos.

Si deseo obtener información sobre el contenido de este directorio, incluyendo los archivos que lo forman y cuántos son éstos, el siguiente script Python me resuelve la tarea:

import os

#Accedo a directorio Documentos

os.chdir('D:/PROGRAMACION/OOoBasic/Documentos')
directorio_actual = os.getcwd()
print(f"Estoy en el directorio: {directorio_actual}")

#Listo los componentes del directorio
lista_archivos = os.listdir('.')

#... y cuento cuántos son 
i = 0

for lista in lista_archivos:
    print(lista)
    i = i + 1

print("Número total de archivos " + str(i))

Tras importar el módulo (import os), me posiciono en el directorio mediante la función chdir() (1) y confirmo mi posición mediante la función os.getcwd().

El siguiente paso consiste en acceder al contenido del directorio mediante la función listdir('.') (2) y, tomando como referencia la lista a la que asigno dicho contenido (lista_archivos = os.listdir('.')), la utilizo como iterable en un ciclo for (for lista in lista_archivos:) que aprovecho para listar los archivos (print(lista)) y para construir un sumatorio sobre la variable i (i = i + 1) que devuelve el número de elementos que contiene el directorio sobre el que trabajamos (print("Número total de archivos " + str(i)))


NOTAS

(1) A la que paso como parámetro la cadena que obtuve antes con Propiedades de Documentos
(2) Cuyo parámetro hace referencia a dicho contenido.

domingo, 15 de junio de 2025

Python. Directorios.


Trabajo con directorios


Hemos visto en [Archivosalgunos de los usos que podemos hacer el módulo os y de otros de funcionalidad similar. Nos corresponde ahora plantear un procedimiento simple de uso combinado de algunas de sus funciones; aquellas que nos permitan hacer lo que necesitamos resolver con frecuencia: el posicionamiento y la creación de directorios como paso previo para la creación de documentos y el archivo controlado de los mismos.


En este caso vamos a plantear la realización de tareas previas de posicionamiento y creación de directorios mediante Python, motivo por el cual planteo como marco de trabajo la ubicación del script en el directorio escritorio y el desarrollo de los procedimientos de trabajo dentro de este directorio.

import os

# Obtener el directorio de trabajo actual
directorio_actual = os.getcwd()
print(f"Directorio actual: {directorio_actual}")

# Cambiar al directorio 'ejemplos' dentro del directorio actual
os.chdir('ejemplos')
# Obtener y mostrar el nuevo directorio de trabajo
nuevo_directorio = os.getcwd()
print(f"Nuevo directorio: {nuevo_directorio}")

# Volver al directorio anterior
os.chdir('..')
# Obtener y mostrar el directorio de trabajo después de volver
directorio_anterior = os.getcwd()
print(f"Directorio después de volver: {directorio_anterior}") 
 
#Nos posicionarnos en una ruta de directorio
os.chdir('C:/Users/alons/OneDrive/Escritorio/LECTURA')
print(os.getcwd()) 

Digo procedimientos en plural porque la idea es mostrar tres procedimientos simples. El primero, el anterior, muestra el modo en que resolvemos cuestiones relativas a nuestro posicionamiento dentro de directorios. Los dos que seguirán nos mostrarán procedimientos de creación de directorios. En cualquier caso, todos ellos inician con la instrucción import os, que es requisito previo, dado que todas las instrucciones son funciones de este módulo.

Pero veamos qué hacemos en el primero:

  • Partimos de identificar en qué directorios nos encontramos (desde qué directorio estamos trabajando)...
  • para lo que empleamos la función os.getcwd()a la cual vamos a recurrir cada vez que deseemos comprobar el resultado de nuestro desplazamiento por los directorios...
  • cosa que hacemos mediante la función os.chdir()la cual admite como parámetro
    • un subdirectorio del directorio actual (vg. os.chdir('ejemplos')),
    • un manejador simple de posiciones (vg os.chdir('..'), que nos posiciona en el directorio inmediatamente superior al que nos encontramos)
    • o una cadena de caracteres que expresa una dirección completa (vg. os.chdir('C:/Users/alons/OneDrive/Escritorio/LECTURA'))
También podemos crear un directorio mediante la función mkdir() en la posición o ruta en la que nos encontremos...

import os

# Crear un directorio simple
try:
    os.mkdir("mi_directorio")
    print("Directorio 'mi_directorio' creado.")
except FileExistsError:
    print("El directorio ya existe.")

... siendo posible controlar el correcto funcionamiento del script mediante el control de excepciones (try...except).

Pero en ocasiones (pronto veremos una) necesitamos automatizar la creación de un sistema de directorios anidados, cosa que podemos hacer recurriendo a la función anterior. Para esta tarea resulta mucho más adecuado hacer uso de la función makedirs(), como muestro en este script.

import os

# Crear un directorio anidado
try:
    os.makedirs("directorio_sup/directorio_med/directorio_inf")
    print("Estructura de directorios anidados creada.")
except FileExistsError:
    print("La estructura de directorios ya existe.")

Si te fijas, mientras mkdir() recibe como parámetro el nombre del directorio a crear (os.mkdir("mi_directorio")), makedirs() recibe una cadena compleja  (os.makedirs("directorio_sup/directorio_med/directorio_inf")). 

Pero ambas funciones comparten la conveniencia de usar un controlador de errores o excepciones (try except) y un comportamiento que puede que se nos pase por alto: haber creado el directorio o el sistema de directorios no implica que nos encontremos dentro de él o en uno de sus niveles; de hacho seguimos estando (seguimos posicionados) en el directorio desde el que los creamos, tal y como nos muestra (de nuevo) el uso de la función os.getcwd(). Si deseamos cambiar de posición deberemos recurrir, como antes explicamos, a la función os.chdir().

viernes, 13 de junio de 2025

Python. Directorios.

 Operaciones con archivos


Trabajar con archivos es tan interesante como el trabajo con directorios, así que dedicamos esta entrada a mostrar algunas de las funciones os que nos permiten obtener información sobre archivos y operar con ellos.


En primer lugar vamos a obtener información relevante sobre un determinado archivo, esto es, algunos de sus metadatos. Para ello crearé un script a partir del ejemplo que muestra [certidevs].

import os

# Posicionamiento en el directorio
os.chdir('D:')
#Identificación confirmatoria como directorio activo
directorio = os.getcwd()
print(f"Ahora estamos en el  directorio: {directorio}")

#Identificación del archivo objeto de análisis 

archivo = 'archivo.pdf'

#Información sobre el nombre del archivo y sobre su existencia
print(f"Vamos a trabajar con el archivo: {archivo}")
print(f"Confirmación de existencia del archivo: {os.path.exists(archivo)}")

#Condicinalidad básica: de existir el archivo (metadatos) (if) y mensaje alternativo (else

if os.path.exists(archivo):
# Obtener el tamaño del archivo
    tamaño = os.path.getsize(archivo)
    print(f"Tamaño del archivo: {tamaño} bytes")  
# Obtener la última modificación (timestamp)
    tiempo_mod = os.path.getmtime(archivo)
# Convertir timestamp a fecha legible
    import datetime
    fecha_mod = datetime.datetime.fromtimestamp(tiempo_mod)
    print(f"Última modificación del archivo: {fecha_mod}")
# Comprobación de permisos
    es_legible = os.access(archivo, os.R_OK)
    es_escribible = os.access(archivo, os.W_OK)
    es_ejecutable = os.access(archivo, os.X_OK)
  print(f"Permisos sobre el archivo - Lectura: {es_legible}, Escritura: {es_escribible}, Ejecución: {es_ejecutable}")

else:
    print ("El archivo NO EXISTE")

En primer lugar importamos el módulo (import os) (1) y nos posicionamos en el directorio donde se ubica el archivo (os.chdir('D:')). Después realizamos varias comprobaciones e informaciones sobre directorio y archivo. Ahora nos interesa especialmente comprobar la existencia del archivo (print(f"Confirmación de existencia del archivo: {os.path.exists(archivo)}")), aunque, como veremos después, ya hemos dispuesto medidas dentro de la opcionalidad posterior (else).

Tras estas comprobaciones desarrollamos una estructura condicional (if os.path.exists(archivo):) (2) dentro de la cual obtenemos información sobre el tamaño del archivo (os.path.getsize()), la última  modificación del mismo (os.path.getmtime()) y una serie de datos sobre permisos (os.access()) (3

Mención especial requiere el procedimiento de conversión del metadato de fecha (de última modificación) (os.path.getmtime(archivo)) en una fecha legible para el usuario. Para ello se requiere recurrir al módulo datetime (import datetime) y a su función de conversión (datetime.datetime.fromtimestamp(tiempo_mod)). Ahora no vamos a tratar sobre este módulo (4), pero dejo indicado un posible tratamiento del mismo en otro momento.

Además de obtener información sobre un archivo, también podemos manipularlo, entendiendo por ello renombrarlo (os.rename()), moverlo a otro directorio (os.replace()) o eliminarlo (os.remove()); y todo ello desde el sistema, sin que sea necesario acceder a él (lectura-escritura). Veamos un sencillo script que da continuidad al anterior (5).

# Renombramos el archivo
os.rename('archivo.pdf', 'archivo_bis.pdf')

# Movemos el archivo
os.replace('archivo_bis.pdf','subdirectorio/archivo.pdf')

# Eliminamos el archivo
os.remove('archivo_copia.pdf')

Obsérvese que la función rename() requiere dos parámetros, bien como string, bien como variables (uno para el nombre antiguo del archivo y otro para el nuevo), al igual que la función replace() (en este caso el primero identifica el archivo a desplazar y el segundo requiere identificar el directorio (que debe existir) y el nombre (que puede ser diferente) del archivo que se desplaza. remove(), por el contrario, sólo requiere identificar el nombre del archivo que se va a eliminar.

NOTAS

(1) En buena lógica (y práctica de programación), ya que después importamos también el módulo datatime (import datetime) deberíamos realizar esta importación en este momento, pero por motivos didácticos la postponemos al momento en que resulta necesaria para la continuidad del script.
(2) Obsérvese que se mantiene el sangrado incluyendo dentro de la condición todas las instrucciones que siguen hasta else
(3) La función access() requiere dos parámetros, el nombre del archivo y la identificación del atributo específico de permiso o acceso. V.g. os.R_OK nos informa si el archivo es legible, esto es, si tiene permisos de lectura.
(4) El módulo datetime es de gran interés para nuestro trabajo dado que nos permite manipular fechas y horas. Información sobre el mismo en [este enlace]
(5) Damos por supuesto que existen los archivos y el directorio que se indican en las instrucciones. Aunque en este script no es imprescindible, en una formulación operativa del mismo el trabajo con el archivo debería condicionarse a la identificación previa de su existencia dentro del directorio en el que estemos trabajando, por lo que debería incluirse dentro de la primera parte del condicional.

jueves, 12 de junio de 2025

Python. Directorios

Operaciones con directorios


Una de las utilidades del módulo os es el trabajo con directorios, así que dedicaré esta entrada a las funciones que nos permiten operar con directorios.


Lo primero que vamos a hacer (1) es conocer en qué directorio estamos trabajando, esto es: en qué directorio se encuentra el archivo .py desde el que solicitamos la información. Se trata, pues, de identificar el directorio en el que se encuentran los archivos que necesitamos en nuestro proyecto, uno de los cuales será, obviamente, el propio archivo .py. Para ello empleamos la función os.getcwd() que nos devuelve la ruta completa del directorio en que nos encontramos (2):

# Obtener el directorio de trabajo actual
directorio_actual = os.getcwd()
print(f"Estás en: {directorio_actual}")

Una vez que sabemos en qué directorio estamos situados, puede interesarnos acceder a otro diferente (3). Para ellos disponemos de la función os.chdir() a la que pasamos como parámetro el string del directorio al que deseamos acceder para, por ejemplo, crear en él un nuevo directorio, para lo que empleamos la función os.mkdir(). Esto es lo que hace el siguiente script.

import os

# Obtenemos el directorio de trabajo inicial

directorio_inicial = os.getcwd()

print(f"Estás en: {directorio_inicial}")

# Cambiamos el directorio de trabajo y obtenemos su ruta

os.chdir('D:/ArchivosVarios')

directorio_actual = os.getcwd()

print(f"Y ahora estás en: {directorio_actual}")

# Y finalmente creamos un nuevo directorio en él.

os.mkdir('nuevo_directorio')

También podemos eliminar un directorio preexistente, tanto si está vacío (os.rmdir())...

os.rmdir('nuevo_directorio') # Módulo os. Elimina un directorio vacío

... como si no lo está, aunque para esto deberemos importar el módulo shutil, que debe ser usado con precaución (4).

import shutil  # Módulo complementario para operaciones de archivos

shutil.rmtree('directorio_con_contenido')  # ¡Cuidado! Elimina todo el contenido

Una vez que accedemos a un directorio nos puede interesar conocer qué subdirectorios y archivos contiene (listdir()), sólo qué archivos (isfile()) o sólo qué directorios (isdir())...

#Ahora listamos los subdirectorios y archivos del directorio actual

lista_conten= os.listdir('.')  # '.' representa el directorio actual

print(f"Contenido del directorio: {lista_conten}")

#Sólo mostramos los archivos

archivos = [f for f in lista_conten if os.path.isfile(f)]

print(f"Archivos: {archivos}")

#Sólo mostramos los subdirectorios

directorios = [d for d in lista_conten if os.path.isdir(d)]

print(f"Directorios: {directorios}")

... aunque es posible que deseemos hacer un listado con información más detallada

for elemento in lista_conten:
    tipo = "Directorio" if os.path.isdir(elemento) else "Archivo"
    tamaño = os.path.getsize(elemento)  # Tamaño en bytes
    print(f"{elemento} - {tipo} - {tamaño} bytes")

NOTAS

(1) Realmente lo primero que haremos será importar el módulo os mediante la instrucción correspondiente (import os), pero esto lo damos por sabido.
(2) La segunda instrucción es la que nos devuelve por pantalla esa ruta. En otras ocasiones puede interesarnos conocerla para trabajar con ella, de ahí el interés por asociarla a una variable. 
(3) La función getcwd() es interesante para conocer desde donde se ejecuta nuestro script, pero necesitamos la función chdir() para navegar por el sistema de archivos.
(4) El módulo shutil permite realizar operaciones de alto nivel con archivos y colecciones de archivos, incluyendo la copia y el borrado de archivos y directorios. Su uso debe ser cuidadoso, ya que podemos eliminar accidentalmente archivos que no deseamos borrar.

Python. Directorios.

Módulo os


Aunque son varios los módulos Python para trabajar con el sistema operativo (1), de momento vamos a trabajar con el módulo os (2) por su universalidad y por las funcionalidades que ofrece.


El módulo os está preinstalado en Python, por lo que no es necesario  instalarlo, pero sí debemos importarlo al inicio del script mediante import os. A partir de este momento tenemos a nuestra disposición...
  • Obtener información del sistema operativo
  • Acceder a variables del entorno del sistema
  • Trabajar con rutas y directorios
  • Listar directorios y archivos
  • Ejecutar comandos del sistema
  • Obtener información sobre metadatos de archivos
  • Realizar operaciones con archivos
  • Gestionar procesos del sistema operativo
El módulo os actúa como intermediario entre Python y el sistema operativo con el que trabajemos, facilitando la ejecución de operaciones que requieren comandos específicos, por lo que es fundamental para automatizar acciones que requieren interactuar con el sistema operativo. 

En esta entrada (y en las que siguen) trataremos sobre aquellas operaciones antes listadas que nos sean de utilidad para nuestros objetivos. Conforme las necesitemos para automatizar procesos, iré ampliando esta subsección del blog.

Empezaré ahora por funciones que nos aportan información sobre el sistema y sobre sus variables.

import os

#Informa sobre qué sistema operativo se está usando. 
print(os.name) #Devuelve nt para windows

#os.environ permite acceder a todas la variables de entorno
usuario = os.environ.get('USERPROFILE') #Permite obtener el valor de una variable
print(usuario)
os.environ['MI_VARIABLE'] = 'valor' # Permite establecer una nueva variable 
for key, value in os.environ.items(): #Lista todas las variables de entorno
   print(f"{key}: {value}")


NOTAS

(1) Para más información sobre os ver [esta web]. Además de os, disponemos de otros módulos para trabajar con el sistema operativo: pathlib, sys, subprocess, io, y shutil. Con independencia de que sean tratados en entradas específicas, en la actual y en las que siguen hablaremos de aquellos que resulten pertinentes para determinadas operaciones.
(2) El módulo os ofrece una amplia gama de funciones para trabajar con el sistema operativo, con independencia de cuál sea éste. Para el desarrollo de esta entrada me basaré en lo que aporta [certidevs] en su web. Muy interesante y didáctica.

jueves, 9 de mayo de 2024

Archivos. OOo Basic

Acceso a un documento

Además de crear nuevos documentos mediante OOo Basic, también es posible acceder a un documento ya creado desde otro que consideramos documento-base. Para ello, y en primer lugar, debemos recordar lo visto en [esta entrada], pero necesitamos algo más. Ese "algo más" es lo que expondré en esta entrada.



Crear un [nuevo documentomediante un script nos aporta muchas posibilidades para nuestro trabajo como SEO, pero acceder a uno ya creado y trabajar con él mediante código nos abre un mudo de posibilidades. Para ello, y en primer lugar, debemos aprender a acceder a esos documentos.

Realmente el procedimiento es muy sencillo con OOo Basic, al menos aparentemente. Por ejemplo:

Sub AbrirHojaCalculo

Dim sRuta As String
Dim mArg()
Dim oHoja As Object

sRuta = ConvertToUrl("C:\Users\XXXX\Desktop\DatosAlumnos.ods")
oHoja = StarDesktop.loadComponentFromURL(sRuta, "_blank", 0, mArg())

End Sub

Este script nos permite acceder a una hoja de cálculo  (DatosAlumnos.ods) ubicada en el escritorio (1) y el que sigue al documento NuevoCreado.odt

Sub AbrirDocumento

Dim sRuta As String
Dim mArg()
Dim oDocumento As Object

sRuta = ConvertToUrl("C:\Users\XXXX\Desktop\NuevoCreado.odt")oDocumento = StarDesktop.loadComponentFromURL(sRuta, "_blank", 0, mArg())

End Sub

Esta posibilidad que nos ofrece OOo Basic de acceder a documentos ya creados tiene potencialmente muchas posibilidades:

  • La creación de una especie de menú de acceso a diferentes documentos según necesidades 
  • El acceso a documentos que contienen informaciones o instrucciones concretas para el manejo del docap o la toma de decisiones (2)
  • El acceso a diferentes docap para la ejecución de un proceso complejo basado en varios soportes.
  • ...

Una vez que accedemos a un documento creado previamente, nos interesa poder trabajar con él, bien desde el documento origen, bien desde el propio documento. Lo primero es similar a lo que hicimos al crear un nuevo documento, según vimos en una [entrada anterior], pero ahora con todas las opciones que ofrece el documento abierto. Lo segundo (trabajar desde el documento al que accedemos) requiere que ese documento abierto sea también un docap.

En ambos casos nos interesa conocer algunas opciones que van más allá del mero acceso al documento. 

Por ejemplo, nos puede interesar acceder al documento en modo plantilla para salvaguardar el original. Para ello añadiremos al script de apertura lo siguiente:

Dim mOpciones(0) As New "com.sun.star.beans.PropertyValue"

mOpciones(0).Name = "AsTemplate"
mOpciones(0).Value = True

Estas instrucciones se ubican antes del código que facilita el acceso al documento y fuerzan a que éste se abra en formato plantilla, aunque originalmente no lo sea. Para ellos sustituiremos la matriz mArg() por la matriz objeto mOpciones(0), también en la instrucción que ordena la apertura del documento:

 StarDesktop.loadComponentFromURL(sRuta, "_blank", 0, mOpciones())

Una opción especialmente interesante cuando el archivo al que accedemos es un docap y queramos trabajar con él como tal, es acceder a su documento-base activando directamente sus macros. Para ello deberemos incluir las siguientes instrucciones al script de acceso (3):

Dim mOpciones(0) As New "com.sun.star.beans.PropertyValue"

mOpciones(0).Name = "MacroExecutionMode"
mOpciones(0).Value = 4

Estas instrucciones habilitan las macros que pudiera contener el documento abierto sin necesidad de que las activemos nosotros. Esto es posible por el valor 4 del parámetro Value.

El resultado final de las modificaciones que hemos ido viendo respecto al script inicial de apertura (por ejemplo) del archivo Writer es el siguiente:

Sub AbrirDocumento

Dim sRuta As String
Dim mOpciones(1) As New "com.sun.star.beans.PropertyValue"
Dim oDocumento As Object
mOpciones(0).Name = "AsTemplate"
mOpciones(0).Value = True
mOpciones(1).Name = "MacroExecutionMode"
mOpciones(1).Value = 4
sRuta = ConvertToUrl("C:\Users\XXXX\Desktop\NuevoCreado.odt")
oDocumento = StarDesktop.loadComponentFromURL(sRuta, "_blank", 0, mOpciones())

End Sub

Y aunque ahora no nos parezca relevante, no quiero dejar de plantear otra interesante posibilidad que nos permite este código de acceso a los documentos creados. Se trata de la posibilidad de acceder a una presentación y que esta se inicie de forma automática (4).

Sub AbrirPresenta()

    Dim sRuta As String
    Dim mOpciones(1) As New "com.sun.star.beans.PropertyValue"
    Dim oDoc As Object
mOpciones(0).Name = "StartPresentation"
mOpciones(0).Value = True
mOpciones(1).Name = "MacroExecutionMode"
mOpciones(1).Value = 4 

sRuta = ConvertToUrl( "C:\Users\XXXX\Desktop\presenta.odp" )
oDoc = StarDesktop.loadComponentFromURL( sRuta, "_blank", 0, mOpciones() )

End Sub

Este script accede a una presentación (presenta.odp) soporte de un docap, activa sus macros y lo inicia de forma de forma automática.

NOTAS

(1) Por motivos de confidencialidad, sustituyo mi identificador de usuario por XXXX. Para que este script funcione realmente, cada cual deberá sustituir XXXX por su identificador. Además, obviamente, deberá existir una hoja de calculo Calc de nombre DatosAlumnos.ods en el escritorio. Cualquier otra ubicación es válida siempre que se referencie correctamente. Para conocer esa dirección es suficiente con hacer clic derecho sobre el archivo y acceder a Propiedades. Lo mismo sirve para el segundo script.
(2) Se trataría de acceder a un documento de cierta extensión y/o que se necesitara consultar con cierta frecuencia a lo largo de la ejecución del docap. En otro caso es suficiente con un MsgBox. Hay que tener en cuenta que igual que accedemos a un archivo Calc o Writer, también podemos acceder a un archivo txt o pdf. Es posible que estos archivos sean abiertos utilizando los servicios LibreOffice compatibles con sus extensiones. Esto va a depender de las extensiones que estén asociados a los servicios de LibreOffice.
(3) Aunque ahora no se exprese (sí en el script reformulado que veremos a continuación), en este ejemplo optamos por aplicar una doble condición: acceder al documento-base del docap como plantilla y activar sus macros. Para ello la matriz mOpciones() consta ahora de dos componentes, de ahí que varíe el numeral (mOpciones(0) -> mOpciones(1)
(4) Para el trabajo ordinario de los SEO esta posibilidad puede resultan de escasa utilidad, pero se me ocurren muchas circunstancias en las que puede ser muy interesante, como, por ejemplo, cuando creamos un recurso de evaluación que requiere contenido gráfico y/o multimedia. Para este formato una presentación es una excelente herramienta. Sobre presentaciones también es posible crear docap.