Um padrão de codificação comum usado na AML era executar uma AML (com parâmetros) dentro de outra AML.
Um aplicativo que estou desenvolvendo atualmente se beneficiaria da capacidade de executar um script Python (com parâmetros) dentro de outro script Python.
No entanto, isso não parece ser nada simples.
Usando o ArcGIS 10, estou experimentando envolver o script Python "interno" em uma ferramenta do ArcGIS que possui os parâmetros. Eu pensei que seria uma questão simples fazer com que o script Python "externo" usasse o arcpy.ImportToolbox para importar a caixa de ferramentas e, em seguida, execute as ferramentas nela. No entanto, nos testes realizados até agora, todas as minhas tentativas de executar a ferramenta "interna" a partir do script "externo" parecem simplesmente ignorar a ferramenta "interna" (nenhum erro é gerado).
Aqui está um código de teste para tentar ilustrar melhor o que estou tentando descrever.
Meu script testinner.py é:
inputString = arcpy.GetParameterAsText(0)
newFC = "C:\\Temp\\test.gdb\\" + inputString
arcpy.Copy_management("C:\\Temp\\test.gdb\\test",newFC)
Meu script 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)
Para testinner.py, sua ferramenta precisa de um único parâmetro String.
Para testouter.py, sua ferramenta precisa de dois parâmetros String
As duas ferramentas são colocadas em um test.tbx.
O test.gdb precisa apenas de uma única classe de recurso vazia chamada test.
Após a montagem acima, a execução da ferramenta testinner com uma string como 'abc' transmitida como parâmetro deve resultar na cópia da classe de recurso 'test' para uma chamada OK 'abc'.
Mas quando você tenta executar a ferramenta testouter com duas sequências como 'uvw' e 'xyz' como parâmetros, a ferramenta testinner no testouter.py parece funcionar OK uma vez, mas envia o ArcMap 10 SP2 no Vista SP2 para um erro grave de aplicativo quando tentando usá-lo pela segunda vez.
O mesmo teste usando o Windows XP SP3 e o ArcGIS Desktop 10 SP2 também produz um erro grave de aplicativo no mesmo ponto.
Respostas:
Aqui está seu exemplo de teste modificado para importar um módulo "utilitário" dentro do script principal e chamar uma função usando os parâmetros lidos pela ferramenta de script:
CopyFeaturesTool.py - Ferramenta de script que lê parâmetros e chama uma função em outro módulo
CopyFeaturesUtility.py - Módulo que possui uma única função
copyFeaturesToTempGDB
. Pode ser importado ou executado de forma independente. Se for executado de forma independente, o código abaixoif __name__ == '__main__'
será executado.Acho que você achará essa abordagem modular muito mais eficiente e lógica depois de se acostumar. A seção Módulos no tutorial padrão do Python também é um bom recurso para entender como a importação funciona.
Para obter exemplos mais específicos do arco-íris, dê uma olhada nos scripts internos da sua
C:\Program Files\ArcGIS\Desktop10.0\ArcToolbox\Scripts
pasta.fonte
Você pode fazer isso importando um módulo (isto é, script) para o script principal e chamando suas funções. Uma demonstração simples está contida nos dois scripts anexos.
para o programa principal e para as funções que estão sendo chamadas
você só precisa garantir que o módulo principal e o módulo filho estejam na mesma pasta. Você pode passar parâmetros para o módulo filho facilmente e, se o módulo filho precisar acessar o arcpy (supondo que você esteja usando a versão 10 do arcmap), basta passar uma referência a ele.
fonte
Importar e executar uma função é a maneira mais limpa de fazê-lo, mas por uma questão de integridade, também existe a
execfile
função interna ( documentação ) que permite executar um arquivo arbitrário no contexto atual.fonte
O método execfile descrito por @JasonScheirer me permitiu reorganizar meu código para isso abaixo e fornece uma solução para o meu problema de teste:
No entanto, isso pode ser complicado quando aplicado a scripts que não são de teste, que são muito mais longos, então usei o trabalho de @ blah238 que endossava a abordagem de @ DanPatterson e surgiu o seguinte código final (teste) que faz exatamente o que eu preciso.
e
fonte