13 votos

¿Por qué es importante el orden de las importaciones en un procesamiento autónomo de PyQGIS script?

Me he encontrado con un problema extraño al ejecutar scripts de procesamiento independientes de PyQGIS. El orden de las importaciones en el script afecta a su ejecución normal.

Puedes reproducir el problema abriendo una consola de Python e introduciendo lo siguiente script (utilizo GNU/Linux, QGIS 2.6.1, processing plugin v.2.2.0-2, y Python 2.7.3):

# Prepare the environment
import sys
from qgis.core import QgsApplication
from PyQt4.QtGui import QApplication
app = QApplication([])
QgsApplication.setPrefixPath("/usr", True)
QgsApplication.initQgis()

# Prepare processing framework 
sys.path.append('/home/YOUR_USER/.qgis2/python/plugins')
from processing.core.Processing import Processing
Processing.initialize()

print Processing.getAlgorithm("qgis:creategrid")

# Exit applications
QgsApplication.exitQgis()
QApplication.exit()

Deberías obtener:

ALGORITHM: Create grid
    HSPACING <ParameterNumber>
    VSPACING <ParameterNumber>
    WIDTH <ParameterNumber>
    HEIGHT <ParameterNumber>
    CENTERX <ParameterNumber>
    CENTERY <ParameterNumber>
    GRIDTYPE <ParameterSelection>
    CRS <ParameterCrs>
    SAVENAME <OutputVector>

Por otro lado, si se cambia el orden de las importaciones (líneas 3 y 4), así

from PyQt4.QtGui import QApplication
from qgis.core import QgsApplication

el script vuelve ahora... None porque no se ha encontrado el algoritmo.

Este problema implica que no se pueden ejecutar algoritmos de procesamiento fuera de QGIS si (por casualidad) se escriben las importaciones en el orden equivocado.

He comprobado en StackOverflow pero según ¿Importa el orden de importación de Python? El orden no debería importar. Además, el Guía de estilo para el código Python nos indica que debemos importar primero las bibliotecas estándar (más genéricas), luego las bibliotecas de terceros relacionadas y, por último, las importaciones específicas de la aplicación local. Creo que PyQt4 se encuentra en la segunda categoría de importaciones, mientras que PyQGIS sería específico de la aplicación local, por lo que las importaciones de PyQt4 deberían ir primero (aunque no soy un experto en esto).

¿Tiene una idea de por qué puede ocurrir esto? ¿Ha experimentado alguna vez algo similar?


EDIT 1: Se han cambiado las importaciones implícitas ( from abc import * ) por otras explícitas (por ejemplo from abc import xyz ) como sugiere @mike-t.

2 votos

Sólo quería decir, excelente pregunta con un breve ejemplo reproducible y pruebas de investigación y análisis de esa investigación.

15voto

Jauder Ho Puntos 3172

tl;dr

import qgis
import PyQt4
etc

es la forma correcta

Versión larga

Sí, el orden de importación puede importar, y en el caso de QGIS 2.0 y superior sí importa.

Siempre hay que importar qgis.core o qgis.gui incluso sólo import qgis es suficiente, antes de importar cualquier cosa de PyQt.

Parece una tontería. ¿Por qué?

En QGIS 2.0 cambiamos al uso de la versión 2 de SIP, lo que hizo que las llamadas a la API fueran más parecidas a las de Python, por ejemplo, convertirá automáticamente los tipos por ti:

1.0 SIP que tenías que hacer:

value.toString()

en 2.0

value

sólo funcionará si se trata de un tipo de cadena en el código C++.

Bien. ¿Y qué?

El problema es que tenemos que establecer la versión de la API a 2 en el código antes de que se establezca mi otra cosa, no se puede establecer de nuevo una vez que se ha establecido. Si importas PyQt primero, establecerá el valor a v1 pero todo en QGIS ahora usa v2. Para arreglar esto, lo establecemos a v2 en qgis.__init__.py pero tenemos que importar qgis primero o si no gana PyQt.

Debido a que todos los plugins en QGIS 2.0 y superiores ahora utilizan SIP v2 cualquier llamada tipo SIP v1 generará un error al ejecutarse.

1 votos

Gracias Nathan, no conocía esas implicaciones. Me pregunto si este tema está bien documentado para los desarrolladores de PyQGIS. Por ejemplo, este muestra cómo debe ser un plugin, y no menciona nada sobre las importaciones. Supongo que este problema no afecta a los plugins de la misma manera que afecta a las aplicaciones/scripts independientes, sin embargo. (Voy a upvote su respuesta en algunos minutos, he gastado todos los votos diarios ya :)).

0 votos

Sí, no afecta a los plugins porque importamos qgis en c++ antes que PyQt.

0 votos

Extraño... me aparece un "ImportError: No hay un módulo llamado PyQt" cuando uso import PyQt aunque import qgis obras. No es que me moleste hasta el punto de tener que hacer una nueva pregunta, sólo me preguntaba si sabéis a qué se debe esto. Uso Windows 7 con las mismas versiones de procesamiento/python que @gcarrillo.

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X