Funcion Popen.

Gabriel Genellina gagsl-py2 en yahoo.com.ar
Lun Mayo 28 12:00:10 CEST 2007


En Mon, 28 May 2007 00:54:54 -0300, Juan Carlos Sey <seymurx en gmail.com>  
escribió:

> Estuve buscando este metodo para comunicarme con un motor de Ajedrez, en
> concreto el engine "Crafty" para quien no sepa de que hablo, es  
> basicamente
> un programa en consola msdos al que puedes introducir los movimientos
> directamente por teclado, es habitual que otros programas usen estos  
> motores
> como corazon del interfaz.
>
> Investigo la forma de comunicarme con el motor y gracias al compañero  
> parece
> que me acerco al problema.
>
> import os
> salida=os.popen("crafty.exe")  #stdout+stderr
> s=salida.read()
> print s
>
> Este sencillo codigo me permite ver la salida del programa desde Python
> (genial lenguaje, aunque estoy empezando) lo que se me escapa es como  
> enviar
> los movimientos, osea veo el out, alguna pista de como hacer lo inverso?  
> el
> input?.

Si estas usando una version razonablemente nueva de Python (2.4 o 2.5)  
entonces lo mas comodo es usar subprocess.

import subprocess
craftyp = subprocess.Popen( ["crafty.exe"],
            stdin=subprocess.PIPE, stdout=subprocess.PIPE,  
stderr=subprocess.STDOUT)

Para enviarle una linea como si la hubieras tipeado por teclado:
craftyp.stdin.write("Texto a enviar\n")

Para leer una linea que haya escrito crafty por pantalla:
linea = craftyp.stdout.readline()

(o .read(1) para leer letra por letra, sin esperar hasta que se complete  
la linea).
Como siempre, "el diablo está en los detalles". Si la interfase es linea a  
linea, simple ("humano" escribe una linea, "crafty" responde con una  
linea, y asi siguiendo) entonces podrias ponerlo dentro de un bucle y leer  
linea por linea como dice arriba.
Si las respuestas son mas largas que una linea (pero hay alguna forma de  
saber que crafty termino de escribir), tambien se podria hacer. El  
problema surge cuando uno, a priori, no sabe si el otro proceso va a  
escribir algo o no: cuando uno llama a readline, o read, o cualquier  
intento de leer algo, y el otro proceso todavia no escribio nada, el  
programa se va a quedar esperando hasta que haya algo para leer. Y si el  
otro proceso a su vez esta esperando que uno le mande una entrada por  
teclado, los dos se quedan bloqueados esperandose entre si. (Este problema  
es independiente de si estas usando popen*, subprocess, o lo que sea)
Hay formas de evitarlo, claro, -usando un segundo thread para leer, por  
ejemplo- pero complican un poco el codigo y siempre conviene saber cómo es  
el tipo de interaccion con el otro proceeso.
Si crafty esta pensado para ser usado de este modo (con una "cascara" que  
lo controla) entonces puede ser facil manejarlo. Si no (y esta pensado  
como un programa autonomo, que escribe cosas por pantalla cuando le da la  
gana, y lee directamente del teclado lo que ingresa el usuario) entonces  
puede ser dificil -o imposible- controlarlo desde fuera.
Asi que, suerte!

-- 
Gabriel Genellina

------------ próxima parte ------------
_______________________________________________
Python-es mailing list
Python-es en aditel.org
http://listas.aditel.org/listinfo/python-es


Más información sobre la lista de distribución Python-es