El gran libro de Python. Marco Buttu
Чтение книги онлайн.
Читать онлайн книгу El gran libro de Python - Marco Buttu страница 24
Paso de los argumentos desde la línea de comandos
Los argumentos pasados al programa desde la línea de comandos son memorizados por Python en una lista accesible mediante el módulo sys. Esta lista se denomina sys.argv y contiene, como primer elemento, el nombre del archivo y como restantes, los otros argumentos pasados desde la línea de comandos:
NOTA
El nombre argv significa argument vector y procede de C, donde se utiliza habitualmente para indicar el parámetro al cual deben asignarse los argumentos pasados desde la línea de comandos:
Los elementos de sys.argv son cadenas, por lo que es preciso convertirlos en el tipo correcto para poder utilizarlos de manera apropiada:
En nuestro script el nombre del directorio de salida se asigna con la instrucción:
La expresión condicional a la derecha del signo igual valora como expresión de prueba la fragmentación de sys.argv, precisamente sys.argv[1:]. Como ya hemos dicho, ante una lista mylist, la fragmentación mylist[i:j] devuelve una lista de los elementos de mylist a partir de aquel con el índice i y hasta aquel con el índice j exclusive. Si el índice j se omite, la fragmentación devuelve todos los elementos a partir de aquel con el índice i, hasta el final de la lista. Consideremos, por ejemplo, el siguiente script:
y lo ejecutamos dos veces. La primera vez no le pasamos ningún argumento desde la línea de comandos, mientras que la segunda le pasamos tres argumentos:
Volviendo a nuestro código, cuando pasamos a python solo el nombre del archivo, la lista sys.argv[1:] queda vacía. Puesto que una lista vacía se valora como False en una prueba de verdad:
la expresión condicional sys.argv[1] ifsys.argv[1:] else 'out' devuelve 'out' y, por tanto, se asigna out_dir_name = 'out'.
En cambio, si además del nombre del archivo se pasa un argumento posterior, entonces sys.argv[1:] no queda vacía y se valora como True. En este caso, por tanto, se asigna out_dir_name = sys.argv[1].
Si quisiéramos realizar el análisis de los argumentos pasados desde la línea de comandos, de manera que aparezcan una ayuda y un mensaje de uso, o bien que se gestionen los errores si se pasan al programa argumentos no válidos, en tal caso será necesario utilizar el módulo argparse de la librería estándar. Dicho módulo realiza el análisis de los elementos de sys.argv, genera automáticamente los mensajes de uso y también gestiona los errores. Veremos un ejemplo de uso de este módulo en el Capítulo 2.
La interacción con el sistema operativo
Nuestro script debe ser capaz de interactuar con el sistema operativo, tanto para crear el directorio de salida, en el caso en que no exista, como para buscar los archivos con extensión .data dentro del directorio de trabajo. Como ya hemos mencionado anteriormente, es el módulo os quien proporciona esta interacción. De hecho, en el script hemos utilizado la función os.mkdir() para crear los directorios de salida:
Si el directorio existe, os.mkdir() genera una excepción de tipo FileExistsError:
Por esta razón, la instrucción que contiene os.mkdir() ha sido insertada dentro de la instrucción try. Así, si el directorio ya existe, se detecta una excepción y el flujo de ejecución pasa directamente a la cláusula except, saltando la print() inmediatamente después de os.mkdir(). A este punto, la suite de la except muestra un mensaje avisando de que el directorio ya existe, y la ejecución pasa a la instrucción for.
La función os.listdir() llamada sin argumentos devuelve una lista de los nombres de archivo y directorios incluidos dentro del directorio actual:
El bucle for itera sobre la lista devuelta por os.listdir() y ejecuta acciones solo si el nombre del archivo acaba en .data. Los archivos con la extensión .data son los siguientes:
Para cada uno de ellos debe crearse un archivo de salida cuyo nombre es otorgado por:
La función os.path.join() une una o más rutas, usando como separador el propio del sistema operativo en uso, por tanto, una barra inclinada en los sistemas Unix-like:
y una barra invertida en los sistemas Windows:
En nuestro caso, la ruta final es el resultado de la unión del nombre del directorio de salida con el nombre del archivo de salida. Por ejemplo, si el nombre del directorio de salida es out_dir_name = 'outdir' y el del archivo de entrada es file_name = '20110315.data', obtenemos:
Si, en lugar de utilizar os.path.join(), hubiéramos unido las rutas insertando el separador específico de nuestro sistema operativo, el script no habría sido portable, es decir, no habríamos podido ejecutarlo del mismo modo en todos los sistemas operativo. Para entendernos, si hubiéramos creado la ruta de este modo:
utilizando el separador específico de los sistemas Windows, nuestro programa no habría funcionado correctamente en los sistemas Unix-like. Consideremos, por ejemplo, el siguiente script:
Cuando lo ejecutamos en Windows, este crea un directorio de nombre out, para crear a continuación en su interior el archivo myfile.dataout. Sin embargo, la ruta pasada a open() utiliza el separador específico de Windows, por lo que el script no es portable. De hecho, en un sistema Unix-like no se crea un archivo myfile.dataout dentro del directorio out, sino un archivo out\myfile.dataout en el directorio actual: