Subsecciones


A. Edición de entrada interactiva y sustitución de historia

Algunas versiones del intérprete de Python permiten la edición de la línea de entrada en curso y la sustitución histórica, servicios similares a los existentes en ksh y bash de GNU. Esto se consigue mediante la biblioteca de GNU Readline, que permite edición estilo Emacs y estilo vi. Esta biblioteca tiene su propia documentación, que no voy a duplicar aquí. Sin embargo, es fácil contar lo más básico. La edición interactiva y el histórico descritos aquí están disponibles opcionalmente en las versiones Unix y CygWin del intérprete.

Este capítulo no documenta los servicios de edición del Paquete PythonWin de Mark Hammond ni el entorno basado en Tk, IDLE, distribuido con Python. La recuperación de historia de la línea de órdenes que funciona en DOS o en NT u otras cosas es también otra historia.


A.1 Edición de línea

Si está disponible, la edición de línea de entrada está activa siempre que el intérprete imprime un indicador principal o secundario. Se puede modificar la línea en curso utilizando los caracteres de control normales de Emacs. Los más importantes son: C-A (Control-A) mueve el cursor al principio de la línea, C-E final. C-K borra hasta el final de la línea, C-Y recupera la última cadena eliminada. C-_ deshace el último cambio realizado (se puede deshacer varias veces).


A.2 Sustitución de historia

La sustitución de historia funciona de la siguiente manera. Cualquier línea de entrada no vacía se guarda en un histórico. Cuando se emite un nuevo indicador, estás situado en una línea nueva debajo de todo el histórico. C-P sube una línea (hacia líneas anteriores) en el histórico y C-N baja una línea. Se puede editar cualquier línea del histórico: aparece un asterisco en frente del indicador para indicar que una línea se ha modificado. Al pulsar la tecla de retorno, se pasa la línea actual al intérprete. C-R comienza una búsqueda inversa incremental y C-S empieza una búsqueda hacia delante.


A.3 Teclas

Es posible personalizar las asignaciones de teclas y otros parámetros de la biblioteca Readline insertando órdenes en un fichero de arranque denominado ~/.inputrc. Las asignaciones de teclas tienen esta forma:

nombre-tecla: nombre-función

o

"cadena": nombre-función

y se cambian las opciones con

set nombre-opción valor

Por ejemplo:

# Prefiero edición tipo vi:
set editing-mode vi

# Editar con una sola línea:
set horizontal-scroll-mode On

# Reasignar varias teclas:
Meta-h: backward-kill-word
"\C-u": universal-argument
"\C-x\C-r": re-read-init-file

Observa que la asignación por omisión del tabulador en Python corresponde a insertar un tabulador, en lugar de la función de completado de nombre de fichero por omisión en Readline. Si insistes, se puede forzar esto poniendo

Tab: complete

en tu fichero ~/.inputrc (por supuesto, esto dificulta teclear líneas de continuación sangradas si usabas el tabulador para ello).

Opcionalmente, está disponible el completado automático de nombres de módulos y variables. Para activarlo en el modo interactivo, añade lo siguiente al fichero de arranqueA.1.

import rlcompleter, readline
readline.parse_and_bind('tab: complete')

Esto asocia el tabulador a la función de completado, por lo que pulsar dos veces el tabulador sugiere terminaciones posibles de la palabra. Busca en los nombres de sentencias Python, las variables locales actuales y los nombres de módulos disponibles. Para expresiones con punto, como cadena.a, primero evalúa la expresión hasta el último "." y sugiere los atributos del objeto resultante. Fíjate que esto puede provocar la ejecución de código definido por la aplicación si hay un objeto con un método __getattr__() como parte de la expresión.

Un fichero de arranque más funcional podría parecerse a este ejemplo. Observa que éste borra los nombres que crea una vez que no se necesitan más; esto se hace porque el fichero de arranque se ejecuta en el mismo espacio nominal que las órdenes interactivas, así que eliminar dichos nombres evita efectos secundarios sobre el entorno interactivo. Podría interesarte mantener algunos de los nombres importados, tales como os, que acaban siendo necesarios en la mayoría de sesiones con el intérprete.

# Añadir auto-completar y un fichero persistente de la historia de las
# órdenes al intérprete interactivo de Python. Necesita Python 2.0 o superior,
# readline. Auto-completar está asociado a la tecla Esc de manera 
# predeterminada (se puede cambiar, leer la doc. de readline).
#
# Guardar el fichero en ~/.pystartup, y establecer una variable de entorno
# que apunte a él: "export PYTHONSTARTUP=/max/home/itamar/.pystartup" en bash.
#
# Ojo: PYTHONSTARTUP *no* expande "~", así que hay que poner la ruta completa
# hasta el directorio del usuario

import atexit
import os
import readline
import rlcompleter

historyPath = os.path.expanduser("~/.pyhistory")

def save_history(historyPath=historyPath):
    import readline
    readline.write_history_file(historyPath)

if os.path.exists(historyPath):
    readline.read_history_file(historyPath)

atexit.register(save_history)
del os, atexit, readline, rlcompleter, save_history, historyPath


A.4 Comentarios

Este servicio es un enorme paso adelante comparado con las anteriores versiones del intérprete. Sin embargo, quedan muchos deseos por cumplir: Sería cómodo que se pusiera automáticamente el sangrado correcto en líneas de continuación (el analizador sabe si hace falta un sangrado). El mecanismo de completado automático podría utilizar la tabla de símbolos del intérprete. También vendría bien una orden para comprobar (y hasta sugerir) las parejas de paréntesis, comillas, etc.



Notas al pie

... arranqueA.1
Python ejecutará el contenido de un fichero identificado por la variable de entorno PYTHONSTARTUP al arrancar una sesión interactiva del intérprete
Consultar en Acerca de este documento... información para sugerir cambios.