ArcPyを使用して別のPythonスクリプト内でPythonパラメーター(パラメーター付き)を実行していますか?


23

AMLで使用される一般的なコーディングパターンは、別のAML内でAML(パラメーター付き)を実行することでした。

現在開発中のアプリケーションは、別のPythonスクリプト内で(パラメーターを使用して)Pythonスクリプトを実行できるという利点があります。

ただし、これはまったく簡単ではないようです。

ArcGIS 10を使用して、「内部の」Pythonスクリプトをパラメーターを持つArcGISツールにラップする実験を行っています。「外部の」Pythonスクリプトでarcpy.ImportToolboxを使用してツールボックスをインポートし、その中でツールを実行するのは簡単なことだと思いました。ただし、これまでのテストでは、「外部」スクリプトから「内部」ツールを実行しようとする試みはすべて、単に「内部」ツールをスキップするように見えます(エラーはスローされません)。

ここに、私が説明しようとしていることをよりよく説明するためのテストコードを示します。

私のtestinner.pyスクリプトは次のとおりです。

inputString = arcpy.GetParameterAsText(0)

newFC = "C:\\Temp\\test.gdb\\" + inputString
arcpy.Copy_management("C:\\Temp\\test.gdb\\test",newFC)

私のtestouter.pyスクリプトは次のとおりです。

import arcpy

inputString1 = arcpy.GetParameterAsText(0)
inputString2 = arcpy.GetParameterAsText(1)

arcpy.ImportToolbox("C:\\Temp\\test.tbx")

arcpy.testinner_test(inputString1)

arcpy.testinner_test(inputString2)

testinner.pyの場合、そのツールには単一のStringパラメーターが必要です。

testouter.pyの場合、そのツールには2つのStringパラメーターが必要です

2つのツールはtest.tbxに配置されます。

test.gdbには、testという名前の単一の空のフィーチャクラスが必要です。

上記を組み立てたら、パラメーターとして渡された「abc」などの文字列を使用してtestinnerツールを実行すると、フィーチャクラス「test」が「abc」という名前のクラスにコピーされます。

ただし、パラメーターとして「uvw」や「xyz」などの2つの文字列を使用してtestouterツールを実行しようとすると、testouter.py内のtestinnerツールは1回正常に実行されるように見えますが、Vista SP2上のArcMap 10 SP2を重大なアプリケーションエラーに送信します二度目にそれを使用しようとしています。

Windows XP SP3とArcGIS Desktop 10 SP2を使用した同じテストでも、同じ時点で深刻なアプリケーションエラーが発生します。


2
これに関する@Danの答えに沿って... .pyファイルを単なる「スクリプト」と考えないでください。これらのモジュールから必要な関数とクラスをインポートすることで、再利用およびリサイクルできるモジュールと考えてください。1つのスクリプトを使用して1つのパラメーターセットを読み取り、必要に応じて他のモジュールの関数を呼び出すことにより、ネストされたGPパラメーターを抽象化します。使用する場合は名前__ ==「__主なあなたの両方のモジュールインポート可能な、まだ使用可能なスタンドアロンを作るためにトリックを。
blah238

出力するダンの例があります:C:\ Temp \ Main_program.py( 'sum some numbers:'、55)( 'sum of squares:'、385)( 'hello from 8:'、[1、2、3 、4、5、6、7、8、9、10])ですが、上記のArcPyの例に適応させるのに苦労しています。ArcPyの例がどのように見えるかについてのさらなる支援があれば幸いです。
PolyGeo

私が追加した答えを参照してください-あなたの例のコンテキストで物事をよりよく説明するのに役立つはずです。
blah238

私はちょうどでPythonモジュールのためのコーディングパターンを取り入れたArcPyテンプレート提供ジェイソンPardyから優れたブログの記事に出くわしたblogs.esri.com/Dev/blogs/geoprocessing/archive/2011/07/21/...
PolyGeo

このリンクはその後移動しており、現在はここにあると考えています:blogs.esri.com/esri/arcgis/2011/08/04/pythontemplate
ndimhypervol

回答:


15

メインスクリプト内に「ユーティリティ」モジュールをインポートし、スクリプトツールによって読み込まれたパラメーターを使用して関数を呼び出すように変更されたテスト例を次に示します。


CopyFeaturesTool.py-パラメーターを読み込み、別のモジュールの関数を呼び出すスクリプトツール

import CopyFeaturesUtility
import arcpy

inputFC = arcpy.GetParameterAsText(0)
outputFCName = arcpy.GetParameterAsText(1)
CopyFeaturesUtility.copyFeaturesToTempGDB(inputFC, outputFCName)

CopyFeaturesUtility.py-単一の機能を持つモジュールcopyFeaturesToTempGDB。インポートするか、スタンドアロンで実行できます。スタンドアロンで実行すると、下のコードif __name__ == '__main__'が実行されます。

import arcpy
import os

def copyFeaturesToTempGDB(inputFeatures, outputName):
    """Copies the input features to a temporary file geodatabase.
    inputFeatures: The input feature class or layer.
    outputName: The name to give the output feature class."""

    tempGDB = r"c:\temp\test.gdb"
    newFC = os.path.join(tempGDB, outputName)
    arcpy.env.overwriteOutput = True
    arcpy.CopyFeatures_management(inputFeatures, newFC)

if __name__ == '__main__':
    inputFC = r"c:\temp\test.gdb\test"
    outputFCName = "testCopy"
    copyFeaturesToTempGDB(inputFC, outputFCName)

このモジュラーアプローチは、慣れてしまえば、はるかに効率的かつ論理的になると思います。標準のPythonチュートリアルのモジュール」セクションも、インポートの仕組みを理解するための優れたリソースです。

arcpy固有の例については、C:\Program Files\ArcGIS\Desktop10.0\ArcToolbox\Scriptsフォルダー内の組み込みスクリプトをご覧ください。


13

これを実現するには、モジュール(スクリプト)をメインスクリプトにインポートし、その関数を呼び出します。簡単なデモが付属の2つのスクリプトに含まれています。

    '''
Main_program.py

demonstrates how to import and call functions from another module
'''
import sys
import CallingFunctions

a_list = [1,2,3,4,5,6,7,8,9,10]
print sys.argv[0]
print CallingFunctions.func1(a_list)
print CallingFunctions.func5(a_list)
print CallingFunctions.func8(a_list)

メインプログラムおよび呼び出されている機能用

'''
Callingfunctions.py

imported into another program giving it access to the functions
'''

def func1(inputs=None):
  x = sum(inputs)
  return "sum some numbers: ", x
'''
more functions
'''
def func5(inputs=None):
  x_sq = 0
  for x in inputs:
    x_sq += x**2
  return "sum of squares: ", x_sq
'''
more functions
'''
def func8(inputs=None):
  return "hello from 8: ", inputs

'''
more functions
'''
if __name__ == "__main__":
  a_list = [1,2,3,4,5,6,7,8,9,10]
  inputs = "test inputs"
  a_dict = {1:[func1([1,2,3]) ],
            5:[func5([1,2,3])],
            8:[func8("inputs to 8")]}
  needed = [1,5,8]
  for akey in needed:
    if akey in a_list:
      action = a_dict[akey]
      print "\naction: ", action

メインモジュールと子モジュールが同じフォルダーにあることを確認する必要があります。パラメーターを子モジュールに簡単に渡すことができ、子モジュールがarcpyへのアクセスを必要とする場合(arcmapのバージョン10を使用している場合)、単に参照を渡します。


6

関数をインポートして実行するのがより簡単な方法ですが、完全を期すために、現在のコンテキストで任意のファイルを実行できるexecfile組み込み関数(documentation)もあります。


0

@JasonScheirerによって記述さexecfileをする方法は、私は以下のように私のコードを再配置させ、私のテスト問題への解決策を提供します。

import arcpy

inputString1 = arcpy.GetParameterAsText(0)
inputString2 = arcpy.GetParameterAsText(1)

arcpy.ImportToolbox("H:/Temp/test.tbx")

# Write second Python script to an ASCII file for first parameter & execute it
f = open("H:/Temp/string1.py","w")
f.write('newFC = "H:/Temp/test.gdb/' + inputString1 + '"' + "\n")
f.write('arcpy.Copy_management("H:/Temp/test.gdb/test"' + ',newFC)')
f.close()
execfile("H:/Temp/string1.py")

# Write third Python script to an ASCII file for second parameter & execute it
f = open("H:/Temp/string2.py","w")
f.write('newFC = "H:/Temp/test.gdb/' + inputString2 + '"' + "\n")
f.write('arcpy.Copy_management("H:/Temp/test.gdb/test"' + ',newFC)')
f.close()
execfile("H:/Temp/string2.py")

ただし、これは非常に長いテスト以外のスクリプトに適用すると面倒になる場合があるため、@ DanPattersonのアプローチを支持する@ blah238の作業を使用し、必要なことを正確に行う次の最終(テスト)コードを作成しました。

# CopyFeaturesTool.py

import CopyFeaturesUtility
import arcpy
outputFCName = arcpy.GetParameterAsText(0)
outputFCName2 = arcpy.GetParameterAsText(1)

CopyFeaturesUtility.copyFeaturesToTempGDB("C:\\Temp\\test.gdb\\test", outputFCName)
CopyFeaturesUtility.copyFeaturesToTempGDB("C:\\Temp\\test.gdb\\test", outputFCName2)

そして

# CopyFeaturesUtility.py

import arcpy
import os

def copyFeaturesToTempGDB(inputFeatures, outputName):
    """Copies the input features to a temporary file geodatabase.
    inputFeatures: The input feature class or layer.
    outputName: The name to give the output feature class."""

    tempGDB = r"C:\Temp\test.gdb"
    newFC = os.path.join(tempGDB, outputName)
    arcpy.env.overwriteOutput = True
    arcpy.Copy_management(inputFeatures, newFC)

if __name__ == '__main__':
    inputFC = r"C:\Temp\test.gdb\test"
    outputFCName = arcpy.GetParameterAsText(0)
    copyFeaturesToTempGDB(inputFC, outputFCName)
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.