शब्दकोश समझ के भीतर SearchCursor में उपयोग किए गए कर्सर को हटाना?


12

यदि यह सुनिश्चित करने के लिए कि इसे हटा दिया गया है, तो कथन के साथ कर्सर को खोलना सबसे अच्छा है, जैसे:

with arcpy.da.UpdateCursor(fc,fields) as cursor:

फिर, यदि एक कर्सर का उपयोग इस तरह से समझने में किया जाता है:

d = {k:v for (k,v) in arcpy.da.SearchCursor(fc,fields)}

क्या समझ में आने के बाद कर्सर को हटाना आवश्यक है?


1
बड़ा सवाल है। क्या आप स्कीमा ताले को संभालने की कोशिश कर रहे हैं? इसी तरह के विषय पर कुछ शुरुआती (ज्यादातर पुरानी) पोस्ट हैं, हालांकि मुझे नए श्रोताओं पर एक निश्चित स्रोत नहीं मिल रहा है da: sgillies.net/2011/02/01/get-with-it.html और help.arcgis.com/ en / arcgisdesktop / 10.0 / help / index.html # //… । विशेष रूप से, पहले लिंक के नीचे @JasonScheirer की टिप्पणियों को देखें।
हारून

जवाबों:


13

क्या यह पूरी तरह से आवश्यक है गलत सवाल पूछना है। सवाल यह है कि क्या यह एक अच्छा विचार है।

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

with arcpy.da.UpdateCursor(fc,fields) as cursor:
    d = {k: v for (k,v) in cursor}

आप जो नहीं जानते हैं वह यह है कि withखंड वास्तव में अतिरिक्त तर्क को आमंत्रित करता है। एक withखंड एक संदर्भ प्रबंधक, जो एक होना आवश्यक है की आवश्यकता है __enter__(लागू जब ब्लॉक दर्ज किया गया है) और __exit__(लागू जब ब्लॉक से बाहर निकल गया है) विधि। विशेष रूप से, __exit__विधि अपवाद के होते हुए भी लागू होती है, यह सुनिश्चित करते हुए कि कार्यक्रम हमेशा त्रुटि पर भी संसाधन जारी करता है। यह आपके कोड को एक संसाधन प्राप्त होने पर और इसे जारी किए जाने पर स्पष्ट दस्तावेज देता है, और यह सुनिश्चित करता है कि संसाधन को जल्द से जल्द जारी किया जा सके।

इसके विपरीत, आप वास्तव में इसे अपने लिए तुरंत बंद करने के लिए रनटाइम पर निर्भर नहीं हो सकते। इसका कारण यह है कि जिस तरह से यह बंद हो जाता है वह वस्तु के विनाशकर्ता को शामिल करने से होता है, जो तुरंत हो सकता है या नहीं। जब एक विध्वंसक का आह्वान किया जाता है, तो पायथन कोई गारंटी नहीं देता है, केवल यह कि यह तब होगा जब ऑब्जेक्ट कचरा एकत्र किया जाएगा। ( यहां देखें ।) वर्तमान में, पायथन को लागू किया गया है ताकि यह जल्द से जल्द हो जाए क्योंकि अब किसी वस्तु का संदर्भ नहीं है। लेकिन गलती से किसी ऑब्जेक्ट के संदर्भ को प्रचारित करना आसान है, और पायथन का रनटाइम बदल सकता है।

दीर्घकालिक रखरखाव पर भी विचार करें। वहाँ यह करने के लिए कोई दीर्घकालिक संदर्भ अब है, लेकिन क्या 6 महीने में होता है जब आप इतना है कि वहाँ कोड संशोधित करना होगा है एक संदर्भ? अगर कोई और ऐसा करता है तो क्या होगा? परिवर्तन करने वाला व्यक्ति किसी withब्लॉक पर स्विच करने के बारे में नहीं सोच सकता है क्योंकि वहां पहले से ही कोई नहीं है। अपने संसाधनों को एक आदत बनाकर सफाई करें , और आपको इससे बहुत कम समस्याएँ होंगी ।

क्या आप वास्तव में कचरा संग्रहण के विवरण को लागू करने के लिए अपने कोड को टाई करना चाहते हैं? क्या आप लगातार इस बारे में सोचना चाहते हैं कि क्या आप एक अपवाद के माध्यम से गलती से एक संदर्भ का प्रचार कर सकते हैं? नहीं, तुम नहीं। कल्पना कीजिए कि जब आर्कपेक में स्क्रिप्ट को लागू किया गया था तब क्या हुआ था। उपयोगकर्ता को केवल फ़ाइल जारी करने के लिए पूरी प्रक्रिया को बंद करने के लिए मजबूर किया जाएगा। तो अपने आप को उस स्थिति में मत रखो। संसाधन स्पष्ट रूप से जारी करें। कोड की एक पंक्ति को सहेजना समस्याओं के जोखिम के लायक नहीं है जो इसका कारण बन सकता है। संदर्भ प्रबंधक पायथन में संसाधनों को प्राप्त करने और जारी करने के लिए मानक तंत्र हैं, और वे इसे बहुत अच्छी तरह से करते हैं।

लब्बोलुआब यह है कि इसे स्पष्ट रूप से जारी नहीं करना एक बुरा विचार है।

यह, निश्चित रूप से, मानता है कि कोड को किसी और को प्रभावित करने की कुछ संभावना है, जैसे कि इसे एक स्क्रिप्ट में रखना जिसे किसी और को चलाने या बनाए रखने की आवश्यकता होगी या यह आपके काम को वितरित करने में देरी कर सकता है यदि आपको आर्कपॉप को सभी तरह से बंद करना है क्योंकि आप अपने परिवर्तनों को सहेज नहीं सकता। यदि आप केवल एक ही व्यक्ति हैं जो किसी समस्या से प्रभावित होगा, तो हर तरह से, आप जो भी चाहते हैं, अच्छी प्रथाओं के सामने उड़ेंगे।


3

नहीं, cursorसमझ में आने के बाद इसे हटाना आवश्यक नहीं है । ए cursorएक वर्ग का एक उदाहरण है, जो एक वस्तु है (अजगर में सब कुछ एक वस्तु है)। प्रत्येक अजगर सत्र में एक सत्र namespaceहोता है जिसमें सत्र में सभी वस्तुओं के संदर्भ होते हैं - इसे एक शब्दकोश की तरह समझें जहां चाबियाँ प्रत्येक वस्तु के संदर्भ हैं, और मूल्य स्वयं ऑब्जेक्ट हैं। जब 'संदर्भ गणना' - उस वस्तु को संदर्भित करने वाली कुंजियों की संख्या - शून्य तक गिर जाती है, तो वस्तु को हटा दिया जाता है और मेमोरी को फिर से आवंटित किया जाता है । जब आप cursorएक समझ का उपयोग करते हैं , तो नामस्थान में उस ऑब्जेक्ट का कोई संदर्भ नहीं होता है। समझ में आने के बाद, ऑब्जेक्ट हटा दिया जाएगा।

नाम स्थान में कोई प्रविष्टि नहीं है, और इसलिए कुछ भी हटाने की आवश्यकता नहीं है। ESRI भी उदाहरण 2 में इस वाक्य रचना को दिखाता है , यहाँ

आगे स्पष्ट करने के लिए, यदि आप चलते हैं:

>>> import arcpy
>>> f = r'C:\Workspace\study_area.shp'
>>> a = arcpy.da.SearchCursor(f, ['*'])

आपको निर्देशिका में एक .lock फ़ाइल दिखाई देगी (अपनी फ़ाइल एक्सप्लोरर की जाँच करें)। कर्सर का संदर्भ है a, जो डिलीट cursorहोने तक (और इसलिए लॉक) बना रहेगा a। इसलिए जब आप दौड़ते हैं:

>>> del(a)

नाम स्थान में प्रविष्टि को हटा दिया जाएगा, और लॉक रिलीज़ होगा (.lock फ़ाइल गायब हो जाएगी)। यदि आप चलाते हैं:

>>> t = [i for i in arcpy.da.SearchCursor(f, ['*'])]

आपको या तो लॉक फ़ाइल दिखाई नहीं देगी, या कमांड पूरी होने पर यह गायब हो जाएगी। नाम स्थान में एक प्रविष्टि के बिना, cursorलगातार नहीं है। tआपके द्वारा बनाई गई सूची को संदर्भित करता है, cursorइसे बनाने के लिए उपयोग नहीं किया जाता है।

सारांशित करने के लिए, आपको केवल cursorsनामस्थान में संदर्भ (यानी जब आपने उन्हें एक चर को सौंपा है, जैसे aऊपर दिए उदाहरण में) हटाने की चिंता करनी होगी ।


2
यह बेहद खराब प्रोग्रामिंग प्रैक्टिस है। यदि कुछ के पास संसाधनों को जारी करने का एक स्पष्ट तरीका है, तो आप इसका उपयोग करते हैं
jpmc26

@ jpmc26, कौन सा भाग "अत्यंत खराब प्रोग्रामिंग अभ्यास" है? सामान्य रूप से समझ? या केवल अगर पुनरावृत्ति समझ के भीतर तत्काल है? मुझे लगा कि बाद के लिए एक मजबूत तर्क यह है कि यह तुरंत संसाधन जारी करता है।
टॉम

@Tom स्पष्ट रूप से संसाधनों को जारी नहीं कर रहा है। समझदारी शानदार उपकरण हैं, और उनके अंदर सामान्य पुनरावृत्तियों को तत्काल पूरी तरह से सामान्य करना है। यहाँ क्या बुरा है कि कर्सर ऑब्जेक्ट फ़ाइल ताले प्राप्त करते हैं और उनमें से कोई स्पष्ट रिलीज़ नहीं है। अधिक विस्तार के लिए मेरा जवाब देखें।
jpmc26

2

यदि डेटासेट के लिए कोई विशेष लॉक मौजूद है, तो टेबल या फ़ीचर क्लास के लिए अपडेट और इंसर्टर्स नहीं बनाए जा सकते हैं। डेटासेट पर अनन्य लॉक के कारण UpdateCursor या InsertCursor फ़ंक्शन विफल हो जाते हैं। यदि ये फ़ंक्शन सफलतापूर्वक एक कर्सर बनाते हैं, तो वे डेटासेट पर एक विशेष लॉक लगाते हैं, ताकि दो स्क्रिप्ट एक ही डेटासेट पर अपडेट या कर्सर नहीं बना सकें।

पायथन में, कर्सर जारी होने तक लॉक जारी रहता है। अन्यथा, अन्य सभी एप्लिकेशन या स्क्रिप्ट अनावश्यक रूप से डेटासेट एक्सेस करने से रोका जा सकता है। एक कर्सर निम्नलिखित में से एक द्वारा जारी किया जा सकता है:

कर्सर को एक बयान के साथ शामिल करना, जो कि कर्सर को सफलतापूर्वक पूरा करने की परवाह किए बिना ताले की रिहाई की गारंटी देगा;

कॉलिंग रीसेट () कर्सर पर;

कर्सर का पूरा होना;

स्पष्ट रूप से पायथन के डेल स्टेटमेंट - ईएसआरआई का उपयोग करके कर्सर को हटाना

आर्कपी.डा कर्सर के साथ लॉक करना बहुत ही मूल आर्करी कर्सर के साथ लॉक करने के समान है।

अपने कोड का परीक्षण करने के बाद, और जैसा कि गर्डर्ड ने बताया, समझ खत्म होने के बाद कर्सर का कोई संदर्भ नहीं है।
इसके अलावा, कॉम्प्रिहेंशन खत्म होने के बाद फीचर क्लास पर कोई लॉक नहीं है।


1
क्या हटाया जा रहा है? समझ खत्म होने के बाद कर्सर ऑब्जेक्ट का कोई संदर्भ नहीं है, इसलिए सिद्धांत रूप में इसे बंद कर दिया जाना चाहिए। ईएसआरआई का कार्यान्वयन व्यवहार करता है या नहीं, जैसा कि आप अपेक्षा करते हैं कि यह एक और सवाल है, और मुझे नहीं लगता कि डॉक्स वास्तव में इसका उत्तर देते हैं।
मिकवेट
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.