Perché l'ordine delle importazioni è importante in uno script di elaborazione PyQGIS autonomo?


13

Ho riscontrato un problema strano durante l'esecuzione di script di elaborazione PyQGIS autonomi. L'ordine delle importazioni nello script influisce sulla sua normale esecuzione.

Puoi riprodurre il problema aprendo una console Python e inserendo il seguente script (utilizzo GNU / Linux, QGIS 2.6.1, plug-in di elaborazione v.2.2.0-2 e 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()

Dovresti ottenere:

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

D'altra parte, se si cambia l'ordine delle importazioni (righe 3 e 4), in questo modo:

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

lo script ora ritorna ... None, perché l'algoritmo non è stato trovato.

Questo problema implica che non è possibile eseguire algoritmi di elaborazione su QGIS se (per caso) si scrivono importazioni nell'ordine sbagliato.

Ho controllato StackOverflow ma secondo Import importa l'ordine di Python , l'ordine non dovrebbe davvero importare. Inoltre, la Guida di stile per Python Code ci dice di importare prima le librerie standard (più generiche), quindi le librerie di terze parti correlate e, infine, le importazioni specifiche delle applicazioni locali. Penso che PyQt4 rientri nella seconda categoria di importazioni, mentre PyQGIS sarebbe specifico per l'applicazione locale, quindi le importazioni di PyQt4 dovrebbero venire prima (non sono un esperto in questo, però).

Hai un'idea del perché ciò possa accadere? Hai mai provato qualcosa di simile?


EDIT 1: Importazioni implicite modificate ( from abc import *) da esplicite (ad es. from abc import xyz) Come suggerito da @ mike-t.


2
Volevo solo dire, ottima domanda con un breve esempio riproducibile e prove di ricerca e analisi di quella ricerca.
user2856

Risposte:


14

tl; dr

import qgis
import PyQt4
etc

è il modo corretto

Versione lunga

Sì, l'ordine di importazione può essere importante e nel caso di QGIS 2.0 e successivi è importante.

Dovresti sempre importare qgis.coreo qgis.gui, anche solo import qgisabbastanza, prima di importare qualsiasi materiale PyQt.

Sembra sciocco. Perché?

In QGIS 2.0 siamo passati all'utilizzo dei binding di versione 2 di SIP che hanno reso le chiamate API più Python come ad esempio convertirà automaticamente i tipi per te:

1.0 SIP che dovevi fare:

value.toString()

nel 2.0

value

funzionerà solo se è un tipo di stringa nel codice C ++.

Ok E allora?

Il kicker è che dobbiamo impostare la versione dell'API su 2 nel codice prima che venga impostata su qualcos'altro, non è possibile impostarla di nuovo una volta impostata. Se si importa prima PyQt, il valore verrà impostato su v1 ma tutto in QGIS ora utilizza v2. Per risolvere questo problema, lo impostiamo su v2 qgis.__init__.pyma dobbiamo qgisprima importare altrimenti PyQt vince.

Poiché tutti i plugin in QGIS 2.0 e versioni successive ora utilizzano SIP v2, qualsiasi chiamata SIP v1 come quella genererà un errore durante l'esecuzione.


1
Grazie Nathan, non ero a conoscenza di tali implicazioni. Mi chiedo se questo problema sia ben documentato per gli sviluppatori PyQGIS. Ad esempio, questo mostra come dovrebbe apparire un plug-in e non menziona nulla sulle importazioni. Immagino che questo problema non influisca sui plugin nello stesso modo in cui influisce su applicazioni / script autonomi, però. (Valuterò la tua risposta tra qualche minuto, ho già speso tutti i voti giornalieri :)).
Germán Carrillo,

Sì, non ha effetto sui plugin perché importiamo qgis in c ++ prima di PyQt.
Nathan W,

Strano ... Ottengo un "ImportError: nessun modulo chiamato PyQt" quando si usa import PyQtsebbene funzioni import qgis. Non che mi preoccupi al punto che devo fare una nuova domanda, mi chiedevo solo se sai perché. Uso Windows 7 con le stesse versioni di elaborazione / python di @gcarrillo.
Joseph,

Questo è un errore di battitura da parte mia. Vedi modifica.
Nathan W,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.