使用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,其工具需要两个String参数

这两个工具放置在test.tbx中。

test.gdb仅需要一个名为test的空要素类。

完成上述组装后,使用传入的字符串(例如abc)作为参数运行testinner工具,应将要素类“ test”复制到一个名为“ abc”的OK。

但是,当您尝试使用两个字符串(例如'uvw'和'xyz')作为参数运行testouter工具时,testouter.py中的testinner工具似乎运行一次,但是在以下情况下将Vista SP2上的ArcMap 10 SP2发送给严重应用程序错误:尝试第二次使用它。

使用Windows XP SP3和ArcGIS Desktop 10 SP2进行的同一测试也会在同一点产生严重的应用程序错误。


2
使用@Dan的答案...不要将.py文件视为“脚本”,而是将它们视为可以通过从那些模块中导入所需的函数和类来重用和回收的模块。通过使用一个脚本读取一组参数,然后根据需要在其他模块中调用函数,来提取那些嵌套的GP参数。使用if name __ =='__ main '技巧使您的模块既可导入也可独立使用。
blah238 2011年

我有Dan的示例正在输出:C:\ Temp \ Main_program.py('总和一些数字:',55)('平方和:',385)('hello from 8:',[1、2、3 ,4、5、6、7、8、9、10]),但正在努力使其适应我上面给出的ArcPy示例。非常感谢任何关于ArcPy示例外观的帮助。
PolyGeo

请参阅我添加的答案-应该有助于更好地说明您的示例。
blah238


此链接此后已经移动,我相信它现在就放在这里:blogs.esri.com/esri/arcgis/2011/08/04/pythontemplate
ndimhypervol

Answers:


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

您可以通过将模块(即脚本)导入主脚本并调用其功能来完成此操作。随附的两个脚本中包含一个简单的演示。

    '''
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),则只需向其传递引用即可。



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")

但是,当将其应用于更长的非测试脚本时,这可能会很麻烦,因此我使用了@ blah238的工作,该工作认可了@DanPatterson的方法,并提出了以下符合我所需的最终(测试)代码。

# 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)
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.