domingo, 12 de febrero de 2017

Redirigiendo la escritura de la salida estándar por defecto (consola) en Python a una variable

La mayoría de los resultados que en Python imprimimos a través de la consola pueden ser redireccionados facilmente a una variable, a un archivo en memoria o en disco, o a un objeto de visualización de PyQt4; como por ejemplo una QTextBrowser. No obstante, existen algunos pocos comandos que, por defecto, no lo hacen y hay que definir la salida estándar (stdout). Entre ellos tenemos la salida, en la Python Consola de QGIS, del comando 'processing.alglist()'; que requiere importar primero el módulo 'processing'.



La salida de 'processing.alglist()' no puede ser asignada a una variable sin antes haber definido la salida estandar. Primero hay que redireccionar la salida estándar a dicho variable y luego restituirla nuevamente a la cónsola si se quiere seguir imprimiendo normalmente a través de ella. Sin embargo, la variable creada es un string enorme que debe ser fraccionado mediante el método 'split', empleando el separador '\n' (final de línea), para que pueda ser ubicado fácilmente el comando 'processing' de nuestro interés usando el módulo de expresiones regulares.

El código a probar se encuentra a continuación:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
import sys, os
import tempfile as tmpf
import processing
import re

def getPat2(keyword, L):
    
    list = [ item for item in L if re.search(keyword, item) is not None ]

    return list  #print list with results

#save a reference to the Python Console of QGIS before reassignment
oldstdout = sys.stdout

#creating a temporary file
file = tmpf.NamedTemporaryFile(delete=False)

file_name = file.name

#reassigning the standard output to temporary file
sys.stdout = file

#printing to temporary file
processing.alglist()

#force the flush to temporary file
sys.stdout.flush()

file.close()

#reassigning the standard output to the Python Console
sys.stdout = oldstdout

#opening temporary file
tmp_file = open(file_name, 'r')

data = tmp_file.read()

data = data.split('\n')

tmp_file.close()

#erasing temporary file
os.unlink(file.name)

Después de ejecutado en la Python Consola de QGIS si se quiere averiguar, por ejemplo, todos los comandos que incluyan la palabra 'dissolve' en su definición se tiene:

1
>>>getPat2('dissolve', data)

lo que produce un resultado similar al de la imagen siguiente:


Allí se observa que existen 6 comandos que incluyen la palabra 'dissolve' en la oferta de geoalgoritmos de 'processing' y así seleccionar el que mejor se adapte a nuestros requerimientos.

No hay comentarios: