为什么在独立的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代码样式指南还告诉我们先导入标准(更通用)的库,然后再导入相关的第三方库,最后再导入特定于本地应用程序的库。我认为PyQt4属于进口的第二大类,而PyQGIS则是针对本地应用的,因此PyQt4的进口应排在首位(不过,我不是专家)。

您是否知道为什么会发生这种情况?您是否经历过类似的经历?


编辑1:按照@ mike-t的建议,将隐式导入(from abc import *)更改为显式导入(例如from abc import xyz)。


2
只是想说,一个很好的问题,上面有一个简短的可重现的例子,以及对该研究进行研究和分析的证据。
user2856 2015年

Answers:


14

tl; dr

import qgis
import PyQt4
etc

是正确的方法

长版

是的,导入顺序很重要,对于QGIS 2.0及更高版本,它确实很重要。

在导入任何PyQt素材之前,您应该始终导入qgis.coreqgis.gui,甚至就import qgis足够了。

真傻。为什么?

在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开发人员是否有充分的记录。例如,显示了插件的外观,但未提及导入。我猜这个问题不会像影响独立应用程序/脚本那样影响插件。(我会在几分钟后为您的答案投票,我已经花了所有的每日票数:))。
赫尔曼·卡里略

是的,它不会影响插件,因为我们在PyQt之前以c ++导入了qgis。
弥敦道W

奇怪... import PyQt虽然import qgis可以使用,但出现“导入错误:没有名为PyQt的模块” 。并不是说让我感到烦恼,我需要问一个新问题,只是想知道您是否知道为什么。我使用Windows 7的处理/ python版本与@gcarrillo相同。
约瑟夫

这是我的错字。参见编辑。
弥敦道W
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.