Pourquoi l'ordre des importations est important dans un script de traitement PyQGIS autonome?

13

J'ai rencontré un problème étrange lors de l'exécution de scripts de traitement PyQGIS autonomes. L'ordre des importations dans le script affecte son exécution normale.

Vous pouvez reproduire le problème en ouvrant une console Python et en entrant le script suivant (j'utilise GNU / Linux, QGIS 2.6.1, le plugin de traitement v.2.2.0-2 et 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()

Vous devez obtenir:

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

En revanche, si vous changez l'ordre des importations (lignes 3 et 4), de cette façon:

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

le script retourne maintenant ... None, car l'algorithme est introuvable.

Ce problème implique que vous ne pouvez pas exécuter des algorithmes de traitement à partir de QGIS si vous (par hasard) écrivez les importations dans le mauvais ordre.

J'ai vérifié dans StackOverflow mais selon l' ordre d'importation de Python , l'ordre ne devrait pas vraiment avoir d'importance. De plus, le Guide de style pour le code Python nous dit d'importer d'abord les bibliothèques standard (plus génériques), puis les bibliothèques tierces associées, et enfin les importations spécifiques aux applications locales. Je pense que PyQt4 se situe dans la deuxième catégorie d'importations, alors que PyQGIS serait spécifique à l'application locale, donc les importations PyQt4 devraient venir en premier (je ne suis pas un expert en la matière, cependant).

Avez-vous une idée de pourquoi cela pourrait arriver? Avez-vous déjà vécu quelque chose de similaire?


EDIT 1: Modification des importations implicites ( from abc import *) par des importations explicites (par exemple, from abc import xyz) comme suggéré par @ mike-t.

Germán Carrillo
la source
2
Je voulais juste dire, excellente question avec un court exemple reproductible et des preuves de recherche et d'analyse de cette recherche.
user2856

Réponses:

14

tl; dr

import qgis
import PyQt4
etc

est la bonne façon

Version longue

Oui, l'ordre d'importation peut être important et dans le cas de QGIS 2.0 et supérieur, il importe.

Vous devez toujours importer qgis.coreou qgis.gui, même si cela import qgissuffit, avant d'importer tout élément PyQt.

Cela semble idiot. Pourquoi?

Dans QGIS 2.0, nous sommes passés à l'utilisation des liaisons de la version 2 de SIP, ce qui a rendu les appels d'API plus Python, par exemple, il convertira automatiquement les types pour vous:

1.0 SIP que vous deviez faire:

value.toString()

en 2.0

value

fonctionnera simplement s'il s'agit d'un type de chaîne dans le code C ++.

Okay, alors quoi

Le plus important est que nous devons définir la version de l'API sur 2 dans le code avant qu'elle ne soit définie quelque chose d'autre, vous ne pouvez pas la définir à nouveau une fois qu'elle a été définie. Si vous importez d'abord PyQt, la valeur sera définie sur v1, mais tout dans QGIS utilise désormais la v2. Afin de résoudre ce problème, nous le définissons sur v2, qgis.__init__.pymais nous devons d' qgisabord importer, sinon PyQt gagne.

Étant donné que tous les plug-ins de QGIS 2.0 et versions ultérieures utilisent désormais SIP v2, tout appel similaire à SIP v1 génère une erreur lors de l'exécution.

Nathan W
la source
1
Merci Nathan, je n'étais pas au courant de telles implications. Je me demande si ce problème est bien documenté pour les développeurs PyQGIS. Par exemple, cela montre à quoi devrait ressembler un plugin et ne mentionne rien sur les importations. Je suppose que ce problème n'affecte pas les plugins de la même manière qu'il affecte les applications / scripts autonomes. (Je voterai pour votre réponse dans quelques minutes, j'ai déjà dépensé tous les votes quotidiens :)).
Germán Carrillo
Oui, cela n'affecte pas les plugins car nous importons des qgis en c ++ avant PyQt.
Nathan W
Étrange ... Je reçois un "ImportError: Aucun module nommé PyQt" lors de l'utilisation import PyQtbien que import qgisfonctionne. Non pas que cela me dérange au point que je dois poser une nouvelle question, je me demandais simplement si vous savez pourquoi. J'utilise Windows 7 avec les mêmes versions de traitement / python que @gcarrillo.
Joseph
C'est une faute de frappe de ma part. Voir modifier.
Nathan W