ArcGIS Python Aracı - ToolValidator Sınıfına Özel Komut Dosyası İçe Aktarma


9

Geçen hafta bir ToolValidator sınıfını özelleştirme hakkında bir soru yayınlamıştım ve çok iyi cevaplar aldım. Önerilen çözümlerle çalışırken, bir db üzerinde sorgular gerçekleştiren özel bir modül oluşturdum ve hem ToolValidator sınıfı (açılır listeler için değer sağlamak için) hem de daha sonra coğrafi işlem komut dosyasında (diğerlerini almak için) çağrılacak parametreleri açılır listelerde seçilen öğelere göre). Ancak, aslında ToolValidator sınıfındaki özel modülü çağırmak gibi görünmüyor. Ben şanssız bir yola eklemek için çalışıyorum. Bu değişiklikleri komut dosyasına uygulamaya çalıştığımda, bir çalışma zamanı hatası alıyorum: [Errno 9] Bozuk dosya tanıtıcı. İçe aktarma satırını yorumlarsam hata olmaz.

sys.path.append('my_custom_module_directory')
import my_custom_module

Birçoğunuz neden sadece ArcObjects ile özel bir araç kullanmıyorum diye soruyor olabilirsiniz. Nedeni, benim son kullanıcıların bilgisayarlarında HERHANGİ dlls kayıt için gerekli ayrıcalıklara sahip olmamasıdır.

GÜNCELLEME: Bu bana ArcGIS 10'da oluyordu. İlginçtir ki, başlangıçta ToolValidator sınıfının initialiazeParameters işlevinin içindeki yola ekliyordum. Eğer eklentiyi ToolValidator sınıfının dışında (yani üstünde) yaparsam, her şey beklendiği gibi çalışır.

sys.path.append('C:/Working/SomeFolder')
import somescript -------->THIS WORKS

class ToolValidator:
  """Class for validating a tool's parameter values and controlling
  the behavior of the tool's dialog."""

  def __init__(self):
    """Setup arcpy and the list of tool parameters."""
    import arcpy
    sys.path.append('C:/Working/SomeFolder')
    import somescript -------> THIS DOESNT WORK
    self.params = arcpy.GetParameterInfo()

GÜNCELLEME 2: Sanırım problemimin gerçek nedenini buldum. Bu yazıdaki kod parçacıklarında, gerçek yollar gibi görünen (ex C: / Working / SomeFolder) sys.path'e ekliyorum. Gerçek ToolValidator sınıfımda, os.path.dirname(__file__)+ "\ my_special_folder ..." kullanarak göreceli bir yol oluşturuyordum . os.path.dirname(__file__)ToolValidator sınıfını içerdiğinden, bu, araç kutusunun yolunu döndüreceğini tahmin ediyordum . Ben bunun böyle olmadığını bulmaya geldim. Anlayabildiğim kadarıyla, ToolValidator sınıfı hiçbir zaman aslında bir .py dosyasına yazılmıyor ve bu kodun bellekte python yorumlayıcısına iletildiğini tahmin ediyorum, bu yüzden __file__işe yaramaz veya geçici bir komut dosyası kalıcı ve sonra yürütülür ( path_to_script) çağrılır, tekrar oluşturulur__file__Faydasız. Eminim ki kaçırmamın başka nedenleri de vardır.

Uzun lafın kısası, eğer sabit kodlanmış bir yol kullanırsam, sys.append her yerde çalışır, göreli yollar ToolValidator sınıfında çok iyi çalışmaz.


Bu 9.3 veya 10'da mı?
Jason Scheirer

Bunu Esri'de yeniden üretmekte sorun yaşıyoruz, nedeni izole edersek 10.0 SP3 için bir düzeltmeyi geri yükleyebiliriz. Bu arada, sanırım ikincisi ile değil, birincisi ile sıkışıp kaldınız.
Jason Scheirer

Yanıtlar:


3

Bunu yapmamın yolu, ArcGIS veya ArcCatalog'u başlattıktan sonra, bir dummy.py komut dosyası çağıran bir kukla aracı ("Bir kez çalıştır") çalıştırmaktır. Bunu yaptıktan sonra sys.argv [0] kullanarak doğrulayıcıdaki python komut dosyalarını içe aktarabilirsiniz. Bu, ilk komut dosyasının bulunduğu klasörü gösterecektir. Daha sonra gerekli betiği de Validator Sınıfına alabilirsiniz.

"Bunu bir kez çalıştır" aracı tarafından çağrılan dummy.py komut dosyası:

import arcgisscripting, sys, os
gp = arcgisscripting.create(9.3)

# set up paths to Toolshare, scripts en Tooldata
scriptPath = sys.path[0]  
toolSharePath = os.path.dirname(scriptPath)
toolDataPath = toolSharePath + os.sep + "ToolData"
gp.addmessage("scriptPath: " + scriptPath)
gp.addmessage("toolSharePath: " + toolSharePath)
gp.addmessage("toolDataPath: " + toolDataPath)

# Use this to read properties, VERY handy!!
import ConfigParser
config = ConfigParser.SafeConfigParser()
config.readfp(open(scriptPath + os.sep + 'properties.ini'))
activeOTAP = config.get('DEFAULT', 'activeOTAP')
activeprojectspace = config.get('DEFAULT', 'activeprojectspace')
activeproject = config.get('DEFAULT', 'activeproject')
activesdeconnection = config.get('DEFAULT', 'activesdeconnection')

Maalesef, biçimlendirmeyi doğru alamıyorum Saygılarımızla, Maarten Tromp


3

Sonunda bu korkunç böcek kırık! Örneğin, göreli bir modülü veya paketi içe aktarmak için değişiklikleri uygulamaya çalıştığınızda aşağıdaki hatayı görebilirsiniz:

resim açıklamasını buraya girin

Seçenek 1:
Yalnızca geliştirici için, modüle giden tam yolu PYTHONPATH öğesine ekleyin . Etkinleşmeden önce ArcMap / ArcCatalog'u yeniden başlatmanız gerekir. Modülü göreceli bir yoldan almak için aşağıdaki kodu kullanın (dağıtım için). Endişelenmeyin, son kullanıcının PYTHONPATH değişkenine herhangi bir eklemeye ihtiyacı yoktur, işe yarayacaktır!

Seçenek 2:
Sabit kodlu yolu eklemek için aşağıdaki koda ek bir satır ekleyin, örneğin: sys.path.append (r "c: \ temp \ test \ scripts")
Konuşlandırmaya hazır olduğunuzda, harici dizin, ancak önemli değil, hepsi eklentinin bilgisayarında çalışmalıdır çünkü eklediğiniz ilk yol göreceli dizin (hedefimiz sadece hata iletişim kutusunu geçmekti).

Her iki seçenek için ortak kod:

import os
import sys

tbxPath = __file__.split("#")[0]
srcDirName = os.path.basename(tbxPath).rstrip(".tbx").split("__")[0] + ".src" 
tbxParentDirPath =  os.path.dirname(tbxPath)
srcDirPath = os.path.join(tbxParentDirPath, srcDirName)

sys.path.append(srcDirPath)
# sys.path.append(r"c:\temp\test\scripts")  #option2

from esdlepy.metrics.validation.LandCoverProportions import ToolValidator

Güncelleme

Veda kötü kesme ve yapıştırma! ToolValidator sınıfının kütüphaneden içe aktarılması için kod örneğini güncelledim. Takım parametreleri ilk ayarlandığında yalnızca bir kez kesip yapıştırıyorum. Bu kod pasajını içe aktarılan ToolValidator doktrininde saklıyorum.

Bu örnekte, kaynak dizin adı tbx adını temel alır. Farklı kaynak dizinleri olan iki araç kutunuz varsa, bu yaklaşım çarpışmaları önler. Kaynak klasör adlandırma için kullandığım standart şöyledir:
TOOLBOXNAME__anything.tbx -> TOOLBOXNAME.src

Neden "__her şey"? İkili dosyalar DVCS'imizde birleştirilemediğinden, kişilere araçlar atayabilir ve değişiklikleri kaybetme konusunda endişelenmeyiz. Takım sonlandığında, kesilir ve master'a yapıştırılır.

Ayrıca, bir açılır listeyi doldurmak için kaynak klasördeki dosyalara erişmem gerekiyordu, içe aktarılan modülünüzden araç kutusuna giden yolu almak için bu yöntemi kullanın:

import __main__
tbxPath = __main__.__file__.split("#")[0]

ToolValidator kodu parametrenin varsayılan değerini ayarlıyor olabilir mi? Komut dosyası aracı özelliklerinde parametrenin 'Varsayılan Değer' ayarını kontrol edin.
blah238

Önerin için teşekkürler. Kontrol ettim ve varsayılan değer araç kutusunda ayarlanmadı ... ancak araç kutusunu kopyaladım ve her şeyi yeniden adlandırdım ve değer her iki kopyada da devam etti. Bu nedenle önbellek fikrimi terk edeceğim ve aslında .tbx dosyasında saklanabileceğini önereceğim, ki bu hala garip bir davranış.
MJ

2

İthalatı doğrulama modülünün en üstüne koymak, ToolValidatorsınıfın dışında benim için iyi çalışıyor gibi görünüyor - 10.0 SP2'deyim. Ancak ithal modül ile hiçbir yerde ama hiçbir şey yapmıyorum updateParameters.

import os
import sys
scriptDir = os.path.join(os.path.dirname(__file__.split("#")[0]), "Scripts") 
sys.path.append(scriptDir)
from someModuleInScriptDir import someFunction

class ToolValidator:
    ...

ToolValidator sınıfının dışında içe aktarmayı denedim, ancak içe aktarma deyiminde başarısız olur. Herhangi bir komut dosyası çalıştırılmadan önce yeni açılmış bir ArcCatalog mu kullanıyordunuz? Bu yüzden ESRI'nin hatayı yeniden üretmekte zorluk çektiğini düşünebilirim ... herhangi bir komut dosyası çalıştırılmadan önce sadece yeni açılan bir uygulamada gerçekleşir.
MJ

Yeni açılan ArcCatalog ile benim için çalışıyor. Sorunun bir işlevi vs bir sınıf ithal mi acaba?
blah238

Teşekkürler, bir şeye devam ediyor olabilirsiniz ... Bir fonksiyonu doğrudan içe aktardığımda çalıştığı bir vakayı hatırlıyorum, biraz daha test yapacağım.
MJ

Çok tuhaf bir davranış ... kırmayı başarana kadar işe yarayacaktı. Kırdıktan sonra, sürekli olarak bir hata atar. PYTHONPATH'ı geliştirici makinesinde kullanmak veya yukarıda açıklandığı gibi ikinci bir sabit kodlu yol eklemek hile yaptı.
MJ

0

Doğrulamamı içe aktarıp mevcut TBX'in araç doğrulamasından çağırarak bir py dosyasına taşıyabildim. Anahtar yapıcı içindeki içe aktarma çağırıyordu. ToolValidator sınıfının dışından çağırırsam içe aktarma başarısız oldu. İşte TBX'in doğrulama sekmesinde ne vardı.

import arcpy
import os
import sys

class ToolValidator(object):
   """Class for validating a tool's parameter values and controlling
   the behavior of the tool's dialog."""

def __init__(self):
   """Setup arcpy and the list of tool parameters."""
   self.scriptDir = os.path.dirname(__file__.split("#")[0])
   sys.path.append(self.scriptDir)
   import ExportParcelIntersected
   self.validator = ExportParcelIntersected.ToolValidator()
   self.params = self.validator.params

 def initializeParameters(self):
   """Refine the properties of a tool's parameters.  This method is
   called when the tool is opened."""
   self.validator.initializeParameters()
   return

 def updateParameters(self):
   """Modify the values and properties of parameters before internal
   validation is performed.  This method is called whenever a parameter
   has been changed."""
   self.validator.updateParameters()
   return

 def updateMessages(self):
   """Modify the messages created by internal validation for each tool
   parameter.  This method is called after internal validation."""
   self.validator.updateMessages()
   return

Doğrulama mantığım daha sonra ExportParcelIntersected.ToolValidator () içinde yaşadı. Nerede daha kolay muhafaza edilebilir.

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.