독립형 PyQGIS 처리 스크립트에서 가져 오기 순서가 중요한 이유는 무엇입니까?


13

독립형 PyQGIS 처리 스크립트를 실행하는 동안 이상한 문제가 발생했습니다. 스크립트에서 가져 오기 순서는 일반 실행에 영향을줍니다.

파이썬 콘솔을 열고 다음 스크립트를 입력하여 문제를 재현 할 수 있습니다 (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 import order matter 에 따르면 순서는 중요하지 않습니다. 또한 Python 코드 용 스타일 가이드는 표준 (보다 일반적인) 라이브러리를 먼저 가져온 다음 관련 타사 라이브러리를 가져오고 마지막으로 로컬 응용 프로그램 별 가져 오기를 알려줍니다. PyQt4는 수입의 두 번째 범주에 속한다고 생각하지만 PyQGIS는 로컬 응용 프로그램에 따라 다르므로 PyQt4 수입이 먼저 나올 것입니다 (나는 이것에 대해 전문가가 아닙니다).

왜 이런 일이 일어날 수 있는지에 대한 아이디어가 있습니까? 비슷한 것을 경험 한 적이 있습니까?


편집 1 : @ mike-t에서 제안한 것처럼 from abc import *명시 적 인 항목 (예 :)으로 암시 적 수입 ( )을 변경했습니다 from abc import xyz.


2
짧은 재현 가능한 예와 그 연구에 대한 연구 및 분석의 증거가있는 훌륭한 질문입니다.
user2856

답변:


14

tl; dr

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가 다른 것을 설정하기 전에 코드에서 API 버전을 2로 설정해야한다는 것입니다. 설정되면 다시 설정할 수 없습니다. PyQt를 먼저 가져 오면 값을 v1로 설정하지만 QGIS의 모든 것은 이제 v2를 사용합니다. 이 문제를 해결하기 위해 v2로 설정 qgis.__init__.py했지만 qgis먼저 가져와야 합니다. 그렇지 않으면 PyQt가 승리합니다.

QGIS 2.0 이상의 플러그인은 모두 SIP v2를 사용하므로 통화와 같은 SIP v1은 실행시 오류를 생성합니다.


1
네이선 고마워, 나는 그런 의미를 몰랐다. 이 문제가 PyQGIS 개발자에게 잘 문서화되어 있는지 궁금합니다. 예를 들어, 쇼는 플러그인과 같이해야하고, 수입에 대해 아무것도 언급하지 않는 방법에 대해 설명합니다. 그러나이 문제는 독립형 응용 프로그램 / 스크립트에 영향을 미치는 것과 같은 방식으로 플러그인에 영향을 미치지 않습니다. (몇 분 안에 답변을 찬성하겠습니다. 모든 일일 투표는 이미 보냈습니다.).
Germán Carrillo

예, PyQt 전에 C ++로 qgi를 가져 오기 때문에 플러그인에 영향을 미치지 않습니다.
Nathan W

이상 import PyQt하지만 import qgis사용할 때 "ImportError : No module PyQt"라는 오류가 발생 합니다. 새로운 질문을해야한다는 점을 귀찮게하는 것이 아니라 왜 그런지 아는지 궁금했습니다. @gcarrillo와 동일한 처리 / 파이썬 버전으로 Windows 7을 사용합니다.
요셉

그것은 저의 오타입니다. 편집을 참조하십시오.
Nathan W
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.