आर्कगिस पायथन टूल - टूलविलेजेटर क्लास में कस्टम स्क्रिप्ट आयात करना


9

मैंने पिछले हफ्ते एक टूलविलेडेटर वर्ग को अनुकूलित करने के बारे में एक प्रश्न पोस्ट किया था और कुछ बहुत अच्छे उत्तर मिले। प्रस्तावित समाधानों के साथ काम करने में, मैंने एक कस्टम मॉड्यूल बनाया है जो db पर क्वेरीज़ निष्पादित करता है, और टूलविलेजिएटर क्लास (ड्रॉप-डाउन सूचियों के लिए मान प्रदान करने के लिए) और बाद में जियोप्रोसेसिंग स्क्रिप्ट (अन्य को प्राप्त करने के लिए) दोनों द्वारा कॉल किया जाएगा। ड्रॉप-डाउन सूचियों में चयनित वस्तुओं पर आधारित पैरामीटर)। हालाँकि, मैं वास्तव में ToolValidator वर्ग में कस्टम मॉड्यूल को कॉल नहीं कर सकता। मैं बिना किसी भाग्य के साथ जुड़ने की कोशिश कर रहा हूं। जब मैं इन परिवर्तनों को स्क्रिप्ट में लागू करने का प्रयास करता हूं, तो मुझे एक रनटाइम त्रुटि मिलती है: [इरनो 9] खराब फ़ाइल विवरणक। अगर मैं आयात लाइन पर टिप्पणी करता हूं, तो कोई त्रुटि नहीं है।

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

आप में से कई लोग पूछ सकते हैं कि मैं सिर्फ आर्कओबजेक्ट्स के साथ एक कस्टम टूल क्यों लागू नहीं करता। इसका कारण यह है कि मेरे अंतिम उपयोगकर्ताओं के पास अपने कंप्यूटर पर किसी भी dll को पंजीकृत करने के लिए निजी कॉलेज नहीं हैं।

अद्यतन: यह मेरे लिए आर्कजीआईएस 10 में हो रहा था। दिलचस्प बात यह है कि, मैं शुरू में टूलविलेगेटर वर्ग के इनिशियजपैरमीटर्स फ़ंक्शन के अंदर पथ से जुड़ रहा था। यदि मैं ToolValidator वर्ग के बाहर (यानी, सबसे ऊपर) करता हूं, तो सब कुछ अपेक्षा के अनुसार काम करता है।

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

अद्यतन 2: मुझे लगता है कि मैंने अपनी समस्या का सही कारण पाया। इस पोस्ट में कोड स्निपेट्स में, मैं यह अपील कर रहा हूं कि sys.path को वास्तविक पथ (ex C: / Working / SomeFolder) दिखाई दें। मेरे वास्तविक ToolValidator वर्ग में, मैं os.path.dirname(__file__)+ \ "my_special_folder ..." का उपयोग करके एक सापेक्ष पथ का निर्माण कर रहा था । मैं अनुमान लगा रहा था कि os.path.dirname(__file__)टूलबॉक्स का मार्ग वापस आ जाएगा, क्योंकि इसमें टूलविलेडेटर वर्ग शामिल है। मुझे पता चला है कि यह मामला नहीं है। जहाँ तक मैं बता सकता हूँ, टूलविलेडेटर वर्ग वास्तव में एक .py फ़ाइल में कभी नहीं लिखा जाता है, और मैं कल्पना करता हूं कि यह कोड स्मृति में अजगर दुभाषिया के लिए पारित किया गया है, इसलिए __file__बेकार है, या कुछ अस्थायी स्क्रिप्ट कायम है और फिर निष्पादन योग्य है ( path_to_script) कहा जाता है, फिर से प्रतिपादन__file__निकम्मा। मुझे यकीन है कि अन्य कारण भी हैं जो मुझे याद आ रहे हैं।

लंबी कहानी छोटी, अगर मैं एक हार्डकोड मार्ग का उपयोग करता हूं, तो sys.append कहीं भी काम करता है, रिश्तेदार पथ टूलविलेलेटर वर्ग में इतनी अच्छी तरह से काम नहीं करते हैं।


क्या यह 9.3 या 10 में है?
जेसन शेखर

अगर हम कारण को अलग करते हैं, तो हम इसे एसपीआर में दोबारा प्रस्तुत करने में परेशानी कर रहे हैं, क्योंकि हम 10.0 एसपी 3 के लिए एक फिक्स बैकपोर्ट कर सकते हैं। इस बीच, मुझे लगता है कि आप पूर्व से चिपके हुए हैं, न कि बाद के उपयोग के पैटर्न से।
जेसन शहीर

जवाबों:


3

जिस तरह से मैं यह कर रहा हूं, आर्कगिस या आर्ककॉस्टिक्स शुरू करने के बाद, पहले एक डमी एरो स्क्रिप्ट को कॉल करके एक डमी टूल ("इसे एक बार चलाएं") चलाएं। ऐसा करने के बाद आप सत्यापनकर्ता में sys.argv [0] का उपयोग करके अजगर लिपियों को आयात कर सकते हैं। यह उस फ़ोल्डर को इंगित करेगा जहां पहली स्क्रिप्ट स्थित थी। इसके बाद आप डे वालिडेटर क्लास में आवश्यक स्क्रिप्ट आयात कर सकते हैं।

"इसे एक बार चलाएं" टूल द्वारा कॉल की गई dummy.py स्क्रिप्ट:

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

क्षमा करें, फ़ॉर्मेटिंग अधिकार नहीं मिल सकता है, Maarten Tromp


3

अंत में इस भयानक बग दरार! उदाहरण के लिए जब आप किसी रिश्तेदार मॉड्यूल या पैकेज को आयात करने के लिए परिवर्तन लागू करने का प्रयास करते हैं, तो आपको निम्न त्रुटि दिखाई दे सकती है:

यहां छवि विवरण दर्ज करें

विकल्प 1:
केवल डेवलपर के लिए, PYTHONPATH के लिए मॉड्यूल का पूरा पथ जोड़ें । इससे प्रभावी होने से पहले आपको ArcMap / ArcCatalog को पुनरारंभ करना होगा। एक रिश्तेदार पथ (तैनाती के लिए) से मॉड्यूल आयात करने के लिए नीचे दिए गए कोड का उपयोग करें। चिंता न करें, अंतिम उपयोगकर्ता को अपने PYTHONPATH चर के लिए किसी भी अतिरिक्त की आवश्यकता नहीं है, यह काम करेगा!

विकल्प 2:
हार्ड-कोडित पथ को जोड़ने के लिए नीचे दिए गए कोड में एक अतिरिक्त पंक्ति जोड़ें, उदाहरण के लिए: sys.path.append (r "c: \ temp \ test \ script")
जब आप तैनात होने के लिए तैयार होते हैं, तो आपके पास एक विलुप्त होने वाली निर्देशिका, लेकिन इससे कोई फर्क नहीं पड़ता, सभी को एंड्यूसर के कंप्यूटर पर काम करना चाहिए क्योंकि आपके द्वारा जोड़ा गया पहला पथ सापेक्ष निर्देशिका था (हमारा लक्ष्य सिर्फ असफलता संवाद को अतीत में लाना था)।

दोनों विकल्पों के लिए आम कोड:

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

अपडेट करें

विदाई बुराई काटने और चिपकाने! मैंने कोड सैंपल को अपडेट कर दिया है ताकि टूलवैलिडेटर क्लास को लाइब्रेरी से आयात किया जाए। जब उपकरण पैरामीटर पहले सेट होते हैं तो मैं केवल एक बार कट और पेस्ट करता हूं। मैं इस कोड स्निपिट को टूलविलेरेटर के डॉकस्ट्रिंग में आयात किया जा रहा है।

इस उदाहरण में, स्रोत निर्देशिका नाम tbx नाम पर आधारित है। यदि आपके पास अलग-अलग स्रोत निर्देशिकाओं के साथ दो टूलबॉक्स हैं, तो यह दृष्टिकोण टकराव से बचता है। स्रोत फ़ोल्डर नामकरण के लिए मैंने जो मानक उपयोग किया है वह इस प्रकार है:
TOOLBOXNAME__anything.tbx -> TOOLBOXNAME.src

क्यों "__anything"? चूंकि द्विआधारी फाइलें हमारे DVCS में विलय नहीं की जा सकती हैं, इसलिए हम व्यक्तियों को उपकरण प्रदान कर सकते हैं और बदलाव खोने के बारे में चिंता नहीं कर सकते। जब उपकरण को अंतिम रूप दिया जाता है, तो इसे काटकर मास्टर में चिपकाया जाता है।

मुझे ड्रॉपडाउन को पॉप्युलेट करने के लिए स्रोत फ़ोल्डर में फ़ाइलों तक पहुँचने की भी आवश्यकता है, इस तरीके का उपयोग अपने आयातित मॉड्यूल के भीतर से टूलबॉक्स तक जाने के लिए करें:

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

क्या ऐसा हो सकता है कि ToolValidator कोड पैरामीटर का डिफ़ॉल्ट मान सेट कर रहा हो? स्क्रिप्ट टूल गुणों में पैरामीटर्स की 'डिफ़ॉल्ट मान' सेटिंग की जाँच करें।
ब्लाह 238

सलाह के लिये धन्यवाद। मैंने जाँच की, और डिफ़ॉल्ट मान टूलबॉक्स में सेट नहीं है ... लेकिन मैंने टूलबॉक्स की प्रतिलिपि बनाई और सब कुछ बदल दिया, और मूल्य अभी भी दोनों प्रतियों में बरकरार है। इसलिए मैं अपने कैश विचार को छोड़ दूंगा और सुझाव दूंगा कि यह वास्तव में .tbx फ़ाइल में संग्रहीत किया जा सकता है, जो अभी भी अजीब व्यवहार है।
एमजे

2

सत्यापन मॉड्यूल के शीर्ष पर आयात करना, ToolValidatorकक्षा के बाहर मेरे लिए ठीक काम करता है - मैं 10.0 SP2 पर हूं। हालांकि मैं आयातित मॉड्यूल कहीं भी साथ लेकिन में कुछ भी नहीं कर रहा हूँ 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 वर्ग के बाहर आयात करने की कोशिश की लेकिन यह आयात विवरण पर विफल हो जाएगा। क्या आप किसी भी स्क्रिप्ट को चलाने से पहले, एक नई खुली हुई आर्ककॉस्टिक्स का उपयोग कर रहे थे? मुझे लगता है कि यही कारण है कि ESRI को त्रुटि को पुन: पेश करने में कठिनाई हो रही है ... यह केवल किसी भी स्क्रिप्ट को चलाने से पहले एक नए खुले अनुप्रयोग में होता है।
एमजे

यह मेरे लिए एक नए खुले आर्ककॉस्टिक्स के साथ काम करता है। मुझे आश्चर्य है कि अगर यह एक वर्ग बनाम एक समारोह का आयात कर रहा है जो समस्या है?
१ah:३२ पर ब्लाह २३ bl

धन्यवाद, आप कुछ पर हो सकते हैं .... मुझे अस्पष्ट रूप से एक मामला याद है जहां यह काम किया था जब मैंने सीधे एक फ़ंक्शन आयात किया था, मैं कुछ और परीक्षण करूंगा।
एमजे

बहुत अजीब व्यवहार ... यह तब तक काम करेगा जब तक मैं इसे तोड़ने में कामयाब नहीं हो जाता। इसे तोड़ने के बाद, यह लगातार एक त्रुटि फेंक देगा। डेवलपर मशीन पर PYTHONPATH का उपयोग करना, या जैसा कि ऊपर उल्लिखित है, एक दूसरी हार्ड कोडित पथ को जोड़ना, इस चाल को किया।
एमजे

0

मैं अपनी मान्यता को एक py फ़ाइल में आयात करके और उसे मौजूदा TBX के टूल सत्यापन के भीतर से कॉल करने में सक्षम था। कुंजी कंस्ट्रक्टर के अंदर आयात को बुला रही थी। अगर मैंने इसे टूलविलेलेटर क्लास के बाहर से बुलाया तो आयात विफल हो गया। यहाँ मैं टीबीएक्स के सत्यापन टैब के अंदर है।

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

मेरा सत्यापन तर्क तब ExportParcelIntersected.ToolValidator () में रहता था। जहां इसे आसान बनाए रखा जा सके।

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.