Chạy các tập lệnh Python (có tham số) trong một tập lệnh Python khác với ArcPy?


23

Một mẫu mã hóa phổ biến được sử dụng trong AML là để chạy AML (có tham số) bên trong AML khác.

Một ứng dụng mà tôi hiện đang phát triển sẽ được hưởng lợi từ việc có thể chạy tập lệnh Python (có tham số) trong tập lệnh Python khác.

Tuy nhiên, điều này dường như không hoàn toàn đơn giản.

Sử dụng ArcGIS 10, tôi đang thử nghiệm gói script Python "bên trong" vào một công cụ ArcGIS có các tham số. Tôi nghĩ sẽ là một vấn đề đơn giản khi có tập lệnh Python "bên ngoài" sử dụng arcpy.ImportToolbox để nhập hộp công cụ và sau đó chạy (các) công cụ bên trong nó. Tuy nhiên, trong thử nghiệm cho đến nay, tất cả các nỗ lực của tôi để chạy công cụ "bên trong" từ tập lệnh "bên ngoài" dường như chỉ đơn giản là bỏ qua công cụ "bên trong" (không có lỗi nào được đưa ra).

Dưới đây là một số mã kiểm tra để thử và minh họa rõ hơn những gì tôi đang cố gắng mô tả.

Kịch bản testinner.py của tôi là:

inputString = arcpy.GetParameterAsText(0)

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

Kịch bản testouter.py của tôi là:

import arcpy

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

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

arcpy.testinner_test(inputString1)

arcpy.testinner_test(inputString2)

Đối với testinner.py công cụ của nó cần một tham số Chuỗi duy nhất.

Đối với testouter.py công cụ của nó cần hai tham số Chuỗi

Hai công cụ được đặt trong test.tbx.

Test.gdb chỉ cần một lớp tính năng trống duy nhất được gọi là test.

Khi bạn đã lắp ráp xong, việc chạy công cụ testinner với một chuỗi như 'abc' được truyền vào làm tham số của nó sẽ dẫn đến lớp tính năng 'test' được sao chép sang một cái gọi là 'abc' OK.

Nhưng khi bạn thử chạy công cụ testouter với hai chuỗi như 'uvw' và 'xyz' làm tham số của nó, công cụ testinner trong testouter.py dường như chạy OK một lần, nhưng gửi ArcMap 10 SP2 trên Vista SP2 đến Lỗi ứng dụng nghiêm trọng khi cố gắng sử dụng nó lần thứ hai

Thử nghiệm tương tự sử dụng Windows XP SP3 và ArcGIS Desktop 10 SP2 cũng tạo ra Lỗi ứng dụng nghiêm trọng tại cùng một điểm.


2
Đi theo câu trả lời của @ Dan về điều này ... đừng nghĩ về các tệp .py giống như "tập lệnh", hãy nghĩ về chúng như các mô-đun bạn có thể tái sử dụng và tái chế bằng cách nhập các hàm và lớp bạn cần từ các mô-đun đó. Tóm tắt các tham số GP lồng nhau đó bằng cách sử dụng một tập lệnh để đọc trong một bộ tham số và sau đó gọi các hàm trong các mô-đun khác của bạn khi cần. Sử dụng thủ thuật if name __ == '__ main ' để làm cho các mô-đun của bạn có thể nhập được và vẫn có thể sử dụng được.
blah238

Tôi có ví dụ của Dan làm việc để xuất ra: C: \ Temp \ Main_program.py ('tổng một số số:', 55) ('tổng bình phương:', 385) ('xin chào từ 8:', [1, 2, 3 , 4, 5, 6, 7, 8, 9, 10]) nhưng đang vật lộn để thích ứng nó với một ví dụ ArcPy như tôi đã đưa ra ở trên. Bất kỳ trợ giúp thêm về những gì một ví dụ ArcPy sẽ trông như thế nào sẽ được đánh giá rất cao.
PolyGeo

Xem câu trả lời tôi đã thêm - sẽ giúp giải thích mọi thứ trong bối cảnh ví dụ của bạn tốt hơn.
blah238

Tôi vừa bắt gặp một bài đăng blog tuyệt vời từ Jason Pardy cung cấp mẫu ArcPy kết hợp mẫu mã hóa cho các mô-đun Python tại blog.esri.com/Dev/bloss/geoprocessing/archive/2011/07/21/ Khăn
PolyGeo

liên kết này đã được chuyển đi và tôi tin rằng nó nằm ở đây ngay bây giờ: blog.esri.com/esri/arcgis/2011/08/04/pythontemplate
ndimhypervol

Câu trả lời:


15

Dưới đây là ví dụ thử nghiệm của bạn được sửa đổi để nhập mô-đun "tiện ích" trong tập lệnh chính và gọi một hàm bằng các tham số được đọc bởi công cụ tập lệnh:


CopyFeaturesTool.py - Công cụ tập lệnh đọc các tham số và gọi một hàm trong mô-đun khác

import CopyFeaturesUtility
import arcpy

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

CopyFeaturesUtility.py - Mô-đun có một chức năng duy nhất copyFeaturesToTempGDB. Có thể được nhập khẩu hoặc chạy độc lập. Nếu chạy độc lập, mã dưới if __name__ == '__main__'được chạy.

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)

Tôi nghĩ rằng bạn sẽ thấy phương pháp mô đun này hiệu quả và hợp lý hơn nhiều khi bạn đã quen với nó. Phần Mô-đun trong hướng dẫn Python chuẩn cũng là một tài nguyên tốt để hiểu cách nhập hoạt động.

Để biết thêm các ví dụ cụ thể về Arcpy, hãy xem các tập lệnh tích hợp trong C:\Program Files\ArcGIS\Desktop10.0\ArcToolbox\Scriptsthư mục của bạn .


13

Bạn có thể thực hiện điều này bằng cách nhập một mô-đun (tức là tập lệnh) vào tập lệnh chính của bạn và gọi các chức năng của nó. Một bản demo đơn giản được chứa trong hai tập lệnh đi kèm.

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

cho chương trình chính và cho các chức năng đang được gọi

'''
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

bạn chỉ cần đảm bảo rằng mô-đun chính và mô-đun con nằm trong cùng một thư mục. Bạn có thể chuyển các tham số cho mô đun con một cách dễ dàng và nếu mô đun con cần truy cập vào arcpy (giả sử bạn đang sử dụng phiên bản 10 của arcmap) chỉ cần chuyển tham chiếu đến nó.


6

Nhập và chạy một chức năng là cách dễ dàng hơn để làm điều đó, nhưng để hoàn thiện, cũng có execfilechức năng ( tài liệu ) tích hợp sẽ cho phép bạn chạy một tệp tùy ý trong ngữ cảnh hiện tại.


0

Các phương pháp execfile mô tả bởi @JasonScheirer cho phép tôi để sắp xếp lại mã của tôi để mà dưới đây và cung cấp một giải pháp cho vấn đề thử nghiệm của tôi:

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

Tuy nhiên, điều này có thể chứng tỏ sự cồng kềnh khi được áp dụng cho (các) tập lệnh không thử nghiệm dài hơn nhiều vì vậy tôi đã sử dụng công việc của @ blah238 tán thành cách tiếp cận của @ DanPatterson và đưa ra mã (thử nghiệm) cuối cùng thực hiện chính xác những gì tôi cần.

# 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)
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.