Чому порядок імпорту має значення в окремому сценарії обробки PyQGIS?


13

Під час запуску автономних сценаріїв обробки PyQGIS я стикався з дивною проблемою. Порядок імпорту в сценарії впливає на його нормальне виконання.

Ви можете відтворити проблему, відкривши консоль Python і ввівши наступний сценарій (я використовую GNU / Linux, QGIS 2.6.1, обробку плагіна v.2.2.0-2 та 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()

Вам слід отримати:

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

З іншого боку, якщо ви переключите порядок імпорту (рядки 3 та 4), таким чином:

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

Тепер сценарій повертається ... None, тому що алгоритм не знайдено.

Це питання означає, що ви не можете запускати алгоритми обробки з QGIS, якщо (випадково) записати імпорт у неправильному порядку.

Я зареєструвався в StackOverflow, але відповідно до того, чи має значення імпорт імпорту Python , порядок насправді не має значення. Більше того, Посібник зі стилю для Python Code вказує нам на те, щоб спочатку імпортувати стандартні (більш загальні) бібліотеки, потім відповідні сторонні бібліотеки та, нарешті, імпорт локальних додатків. Я думаю, що PyQt4 лежить у 2-й категорії імпорту, тоді як PyQGIS був би специфічним для місцевого застосування, тому імпорт PyQt4 повинен стати першим (я, однак, не знаю цього питання).

Чи маєте ви уявлення, чому це могло статися? Ви коли-небудь відчували щось подібне?


EDIT 1: Змінено неявний імпорт ( from abc import *) за допомогою явних (наприклад, from abc import xyz) пропозицій @ mike-t.


2
Просто хотів сказати, відмінне запитання з коротким відтворюваним прикладом та доказами дослідження та аналізу цього дослідження.
user2856

Відповіді:


14

тл; д-р

import qgis
import PyQt4
etc

це правильний шлях

Довга версія

Так, замовлення на імпорт може мати значення, і у випадку QGIS 2.0 і вище це має значення.

Ви завжди повинні імпортувати qgis.coreабо qgis.guiнавіть import qgisдостатньо, перш ніж імпортувати будь-які матеріали PyQt.

Це здається дурним. Чому?

У QGIS 2.0 ми перейшли до використання прив’язки SIP версії 2, що зробило API викликів більш Python, наприклад, воно автоматично перетворить типи для вас:

1.0 SIP, що вам потрібно було зробити:

value.toString()

у 2.0

value

просто працюватиме, якщо це тип рядка в коді C ++.

Гаразд, що ж

Задача полягає в тому, що ми повинні встановити версію API на 2 в коді, перш ніж вона буде встановлена ​​моїм чимось іншим, ви не можете встановити її знову, як тільки вона була встановлена. Якщо ви імпортуєте PyQt спочатку, він встановить значення v1, але все в QGIS зараз використовує v2. Для того, щоб виправити це, ми встановимо його на v2, qgis.__init__.pyале нам потрібно імпортувати qgisперше, інакше виграє PyQt.

Оскільки всі плагіни в QGIS 2.0 і вище використовуються SIP v2, будь-які дзвінки, подібні SIP v1, призведе до помилки при запуску.


1
Дякую, Натане, я не знав таких наслідків. Цікаво, чи добре це питання документоване для розробників PyQGIS. Наприклад, це показує, як повинен виглядати плагін, і нічого не згадує про імпорт. Я думаю, ця проблема не впливає на плагіни так само, як і на окремі додатки / сценарії. (Я підтверджую вашу відповідь через кілька хвилин, я витратив усі голоси щоденно вже :)).
Герман Каррільо

Так, плагіни не впливають, оскільки ми імпортуємо qgis в c ++ перед PyQt.
Натан Ш

Дивно ... Я отримую "ImportError: Немає модуля з ім'ям PyQt" при використанні, import PyQtхоча import qgisпрацює. Не те, що мене турбує до того, що мені потрібно задати нове запитання, просто цікавилось, чи знаєте ви, чому це так. Я використовую Windows 7 з тією ж версією обробки / python, що і @gcarrillo.
Йосип

Це друкарська справа. Див. Редагування.
Nathan W
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.