ArcPy ile Python komut dosyalarını (parametrelerle birlikte) başka bir Python komut dosyasında çalıştırmak?


23

AML'de kullanılan ortak bir kodlama modeli, bir AML'yi (parametreleriyle birlikte) başka bir AML'nin içinde çalıştırmaktı.

Geliştirmekte olduğum bir uygulama, başka bir Python betiği içinde bir Python betiği (parametreleri ile) çalıştırabilmekten fayda sağlayacaktır.

Ancak, bu hiç de basit görünmüyor.

ArcGIS 10 kullanarak, "inner" Python betiğini, parametreleri içeren bir ArcGIS aracına sarmayı deniyorum. "Dış" Python betiğinin araç kutusunu içe aktarmak ve içindeki araçları çalıştırmak için arcpy.ImportToolbox kullanmasının basit bir mesele olacağını düşündüm. Bununla birlikte, bugüne kadar yapılan testlerde, "iç" aracını "dış" komut dosyasından çalıştırma girişimlerimin tümü "iç" aracını atlıyor gibi görünüyor (hata atılmıyor).

Anlatmaya çalıştığım şeyi daha iyi denemek ve göstermek için bazı test kodları.

Testinner.py betiğim:

inputString = arcpy.GetParameterAsText(0)

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

Testouter.py betiğim:

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 için aracı tek bir String parametresine ihtiyaç duyar.

Testouter.py için aracı iki String parametresine ihtiyaç duyar

İki araç bir test.tbx dosyasına yerleştirilir.

Test.gdb sadece test adı verilen boş bir özellik sınıfına ihtiyaç duyar.

Yukarıdakileri topladıktan sonra, testinner aracını 'abc' gibi bir dizeyle çalıştırmak, parametre olarak 'test' özellik sınıfının 'abc' OK adlı birine kopyalanmasıyla sonuçlanmalıdır.

Ancak, test aracını parametresi olarak 'uvw' ve 'xyz' gibi iki dizeyle çalıştırmayı denediğinizde, testouter.py içindeki testinner aracı bir kez tamam çalışıyor gibi görünüyor, ancak Vista SP2'deki ArcMap 10 SP2'yi ciddi bir Uygulama Hatası'na gönderdiğinde ikinci kez kullanmaya çalışıyorum.

Windows XP SP3 ve ArcGIS Desktop 10 SP2'yi kullanan aynı test, aynı noktada Ciddi bir Uygulama Hatası da veriyor.


2
@ Dan'in bu konudaki cevabına gitmek ... .py dosyalarını tıpkı "betikler" olarak düşünmeyin, ihtiyaç duyduğunuz fonksiyonları ve sınıfları bu modüllerden içe aktararak yeniden kullanabileceğiniz ve geri dönüştürebileceğiniz bir modül olarak düşünün. İç içe geçmiş GP parametrelerini, bir parametre setinde okumak için bir komut dosyası kullanarak soyutlayın ve ardından gerektiği gibi diğer modüllerde işlevleri çağırın. Modüllerinizi hem içe aktarılabilir hem de kullanılabilir duruma getirmek için bağımsız hale getirmek için , if = __= '__ main ' numarasını kullanın.
blah238

Dan'ın çıktısını almaya çalışan örneği var: C: \ Temp \ Main_program.py ('bazı sayıları topla:', 55) ('karelerin toplamı:', 385) ('merhaba 8:', [1, 2, 3 , 4, 5, 6, 7, 8, 9, 10]) ama yukarıda verdiğim gibi bir ArcPy örneğine uyarlamak için mücadele ediyorum. Bir ArcPy örneğinin nasıl görüneceği konusunda daha fazla yardım çok takdir edilecektir.
PolyGeo

Eklemiş olduğum cevaba bakınız - örneklerin bağlamında işleri daha iyi açıklamaya yardımcı olmalı.
blah238

Sadece at Python modülleri için kodlama desen içeren bir ArcPy şablonu sağlar Jason PARDY mükemmel bir blog yayınına rastladım blogs.esri.com/Dev/blogs/geoprocessing/archive/2011/07/21/...
PolyGeo

bu bağlantı o zamandan beri taşındı ve şu an burada olduğuna inanıyorum: blogs.esri.com/esri/arcgis/2011/08/04/pythontemplate
ndimhypervol

Yanıtlar:


15

Ana komut dosyasına bir "yardımcı program" modülünü içe aktarmak ve komut dosyası aracı tarafından okunan parametreleri kullanarak bir işlevi çağırmak için değiştirilmiş test örneğiniz:


CopyFeaturesTool.py - Parametrelerde okuyan ve başka bir modüldeki bir işlevi çağıran komut dosyası aracı

import CopyFeaturesUtility
import arcpy

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

CopyFeaturesUtility.py - Tek bir işlevi olan modül copyFeaturesToTempGDB. Bağımsız olarak alınabilir veya çalıştırılabilir. Bağımsız if __name__ == '__main__'olarak çalıştırılırsa, altındaki kod çalıştırılır.

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)

Bu modüler yaklaşımı, alıştıktan sonra çok daha verimli ve mantıklı bulacağınızı düşünüyorum. Standart Python eğitimde Modülleri bölümünde de nasıl ithal çalıştığını anlamak için iyi bir kaynaktır.

Daha fazla arcpy'e özgü örnekler için, C:\Program Files\ArcGIS\Desktop10.0\ArcToolbox\Scriptsklasörünüzdeki dahili komut dosyalarına bir göz atın .


13

Bunu, ana betiğinize bir modül (örn. Script) alarak ve işlevlerini çağırarak yapabilirsiniz. Ekteki iki senaryoda basit bir demo bulunmaktadır.

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

Ana program için ve çağrılan fonksiyonlar için

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

sadece ana modül ile alt modülün aynı klasörde olduğundan emin olmalısınız. Parametreleri kolayca çocuk modülüne iletebilirsiniz ve eğer çocuk modülünün arcpy'ye erişmesi gerekiyorsa (10 arcmap versiyonunu kullandığınız varsayılırsa) basitçe bir referans verin.


6

Bir işlevi içe aktarma ve çalıştırma bunu yapmanın daha temiz yoludur, ancak tamlık uğruna , geçerli bağlamda rasgele bir dosya çalıştırmanıza izin veren execfileyerleşik bir işlev de ( belgeler ) vardır.


0

@JasonScheirer tarafından açıklanan execfile yöntemi beni aşağıda olduğu için kodumu yeniden düzenlemek için izin ve benim test soruna bir çözüm sağlar:

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

Bununla birlikte, bu çok daha uzun olan test dışı senaryolara uygulandığında hantal olabilir, bu yüzden @ blah238'in @ DanPatterson'ın yaklaşımını onaylayan ve tam olarak ihtiyacım olanı yapan aşağıdaki final (test) kodunu içeren çalışmasını kullandım.

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

ve

# 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)
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.