การลบเคอร์เซอร์ที่ใช้ใน SearchCursor ภายในความเข้าใจในพจนานุกรม?


12

หากเป็นการดีที่สุดที่จะเปิดเคอร์เซอร์โดยใช้คำสั่ง with เพื่อให้แน่ใจว่ามันถูกลบออกไปเช่น:

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

จากนั้นหากเคอร์เซอร์ถูกใช้เป็น iterable ในความเข้าใจเช่นนั้น:

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 / ช่วยเหลือ / 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__วิธีการนี้ถูกเรียกใช้โดยไม่คำนึงว่ามีข้อยกเว้นเกิดขึ้นหรือไม่เพื่อให้มั่นใจว่าโปรแกรมจะเผยแพร่ทรัพยากรเสมอแม้เกิดข้อผิดพลาด สิ่งนี้จะให้เอกสารรหัสของคุณอย่างชัดเจนว่าเมื่อใดที่มีการรับทรัพยากรและเมื่อมีการเผยแพร่และช่วยให้มั่นใจได้ว่าทรัพยากรจะได้รับการเผยแพร่โดยเร็วที่สุด

ในทางตรงกันข้ามคุณไม่สามารถพึ่งพารันไทม์เพื่อปิดมันได้อย่างน่าอัศจรรย์สำหรับคุณ เนื่องจากวิธีการปิดคือการเรียกตัวทำลายของวัตถุซึ่งอาจหรืออาจจะไม่เกิดขึ้นทันที Python ไม่รับประกันใด ๆ เมื่อมีการเรียกใช้ destructor เฉพาะในที่สุดเมื่อวัตถุนั้นถูกรวบรวมขยะ (ดูที่นี่ ) ปัจจุบันมีการใช้งาน Python เพื่อให้เกิดขึ้นทันทีที่ไม่มีการอ้างอิงไปยังวัตถุอีกต่อไป แต่มันง่ายที่จะเผยแพร่การอ้างอิงไปยังวัตถุโดยไม่ตั้งใจและรันไทม์ของ Python อาจเปลี่ยนไป

พิจารณาการบำรุงรักษาในระยะยาวด้วย ไม่มีการอ้างอิงในระยะยาวก็ตอนนี้ แต่สิ่งที่เกิดขึ้นในรอบ 6 เดือนเมื่อคุณต้องแก้ไขโค้ดเพื่อให้มีคือการอ้างอิง? เกิดอะไรขึ้นถ้ามีคนอื่นทำมัน? บุคคลที่ทำการเปลี่ยนแปลงอาจไม่คิดว่าจะเปลี่ยนเป็นwithบล็อกเนื่องจากยังไม่มีบล็อก ทำความสะอาดทรัพยากรให้เป็นนิสัยและคุณจะมีปัญหาน้อยลง

คุณต้องการผูกรหัสของคุณกับรายละเอียดการใช้งานการรวบรวมขยะหรือไม่ คุณต้องการคิดอย่างต่อเนื่องว่าคุณอาจเผยแพร่ข้อมูลอ้างอิงโดยไม่ตั้งใจหรือไม่? ไม่คุณทำไม่ได้ ลองนึกภาพว่ามันเกิดขึ้นเมื่อสคริปต์ถูกเรียกใช้ใน ArcMap ผู้ใช้จะถูกบังคับให้ปิดกระบวนการทั้งหมดเพียงเพื่อปล่อยไฟล์ ดังนั้นอย่าทำให้ตัวเองอยู่ในตำแหน่งนั้น ปล่อยทรัพยากรอย่างชัดเจน การบันทึกรหัสหนึ่งบรรทัดนั้นไม่คุ้มกับความเสี่ยงของปัญหาที่อาจเกิดขึ้น ผู้จัดการบริบทเป็นกลไกมาตรฐานสำหรับการรับและการปล่อยทรัพยากรใน Python และพวกเขาทำได้ดีมาก

บรรทัดล่างคือการไม่ปล่อยอย่างชัดเจนเป็นความคิดที่ไม่ดี

แน่นอนว่ารหัสนี้มีความเป็นไปได้ที่จะส่งผลกระทบต่อคนอื่นเช่นวางไว้ในสคริปต์ที่บุคคลอื่นจะต้องเรียกใช้หรือบำรุงรักษาหรืออาจล่าช้าส่งงานของคุณหากคุณต้องปิด ArcMap ไปตลอดทางเพราะคุณ ไม่สามารถบันทึกการเปลี่ยนแปลงของคุณ หากคุณเป็นคนเดียวที่จะได้รับผลกระทบจากปัญหาดังนั้นโดยวิธีการทั้งหมดแล้วให้บินไปพบกับแนวปฏิบัติที่ดีที่คุณต้องการ


3

ไม่ไม่จำเป็นต้องลบcursorหลังจากใช้ในความเข้าใจ A cursorเป็นตัวอย่างของชั้นเรียนซึ่งเป็นวัตถุ (ทุกอย่างในหลามเป็นวัตถุ) ทุก ๆ ไพ ธ อนนั้นnamespaceมีการอ้างอิงไปยังวัตถุทั้งหมดในเซสชั่น - คิดว่ามันเหมือนพจนานุกรมที่มีการอ้างอิงคีย์กับแต่ละวัตถุและค่าเป็นวัตถุเอง เมื่อ 'นับอ้างอิง - จำนวนของปุ่มที่อ้างถึงวัตถุที่ - ลดลงไปอยู่ที่ศูนย์วัตถุจะถูกลบออกและหน่วยความจำใหม่จัดสรร เมื่อคุณใช้ a cursorในความเข้าใจไม่มีการอ้างอิงถึงวัตถุนั้นใน namespace หลังจากทำความเข้าใจเสร็จแล้ววัตถุจะถูกลบ

ไม่มีรายการในเนมสเปซดังนั้นจึงไม่จำเป็นต้องลบอะไรเลย ESRI ยังแสดงให้เห็นถึงรูปแบบนี้ใน2 ตัวอย่างที่นี่

หากต้องการชี้แจงเพิ่มเติมหากคุณเรียกใช้:

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

คุณจะเห็นไฟล์. ล็อคปรากฏขึ้นในไดเรกทอรี (ตรวจสอบไฟล์ explorer ของคุณ) การอ้างอิงถึงเคอร์เซอร์คือaซึ่งจะทำให้cursor(และดังนั้นการล็อค) ยังคงมีอยู่จนกว่าaจะถูกลบ ดังนั้นเมื่อคุณเรียกใช้แล้ว:

>>> del(a)

รายการในเนมสเปซจะถูกลบออกและการล็อคจะปล่อย (ไฟล์. lock จะหายไป) หากคุณทำงาน:

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

คุณจะไม่เห็นไฟล์ล็อคหรือมันจะหายไปเมื่อคำสั่งเสร็จสิ้น หากไม่มีรายการในเนมสเปซcursorจะไม่คงอยู่ tอ้างถึงรายการที่คุณเพิ่งสร้างไม่ใช่การcursorใช้เพื่อสร้าง

ในการสรุปคุณต้องกังวลเกี่ยวกับการลบcursorsเมื่อมีการอ้างอิงในเนมสเปซเท่านั้น (เช่นเมื่อคุณกำหนดให้กับตัวแปรเช่นaในตัวอย่างด้านบน)


2
นี่เป็นวิธีการเขียนโปรแกรมที่แย่มาก หากสิ่งที่มีวิธีที่ชัดเจนของการปล่อยทรัพยากรที่คุณใช้มัน
jpmc26

@ jpmc26 ส่วนไหนคือ "การฝึกเขียนโปรแกรมที่แย่มาก" ความเข้าใจโดยทั่วไป? หรือเฉพาะในกรณีที่ iterable เป็นตัวอย่างในความเข้าใจ? ฉันคิดว่าข้อโต้แย้งที่แข็งแกร่งอย่างหนึ่งสำหรับสิ่งหลังคือมันปล่อยทรัพยากรทันที
Tom

@Tom ไม่ปล่อยทรัพยากรอย่างชัดเจน ความเข้าใจเป็นเครื่องมือที่ยอดเยี่ยมและการทำให้เป็นค่าปกติในตัวมันเป็นเรื่องปกติ สิ่งที่ไม่ดีในที่นี้คือวัตถุเคอร์เซอร์จะได้รับการล็อคไฟล์และไม่มีการปล่อยให้ชัดเจน ดูคำตอบของฉันสำหรับรายละเอียดเพิ่มเติม
jpmc26

2

ไม่สามารถสร้างเคอร์เซอร์อัปเดตและแทรกสำหรับตารางหรือคุณลักษณะคลาสหากมีการล็อคแบบเอกสิทธิ์สำหรับชุดข้อมูลนั้น ฟังก์ชัน UpdateCursor หรือ InsertCursor ล้มเหลวเนื่องจากการล็อกแบบเอกสิทธิ์เฉพาะบุคคลบนชุดข้อมูล หากฟังก์ชันเหล่านี้สร้างเคอร์เซอร์ได้สำเร็จพวกเขาจะใช้การล็อคแบบเอกสิทธิ์เฉพาะบุคคลบนชุดข้อมูลเพื่อให้สคริปต์สองตัวไม่สามารถสร้างการอัปเดตหรือแทรกเคอร์เซอร์บนชุดข้อมูลเดียวกัน

ใน Python การล็อคยังคงอยู่จนกว่าเคอร์เซอร์จะถูกปลดออก มิฉะนั้นแอปพลิเคชั่นหรือสคริปต์อื่น ๆ สามารถป้องกันได้โดยไม่จำเป็นจากการเข้าถึงชุดข้อมูล เคอร์เซอร์สามารถถูกปล่อยโดยหนึ่งในสิ่งต่อไปนี้:

รวมถึงเคอร์เซอร์ในคำสั่ง a ด้วยซึ่งจะรับประกันการปลดล็อคโดยไม่คำนึงว่าเคอร์เซอร์จะเสร็จสมบูรณ์หรือไม่

กำลังรีเซ็ต () บนเคอร์เซอร์;

ความสมบูรณ์ของเคอร์เซอร์

การลบเคอร์เซอร์อย่างชัดเจนโดยใช้คำสั่ง del Python - ESRI

การล็อคด้วยเคอร์เซอร์ arcpy.da นั้นเหมือนกับการล็อคด้วยเคอร์เซอร์ arcpy ดั้งเดิม

หลังจากทดสอบโค้ดของคุณและตามที่เบอร์ดานชี้ให้เห็นจะไม่มีการอ้างอิงไปยังเคอร์เซอร์หลังจากที่ความเข้าใจจบลง
นอกจากนี้ยังไม่มีการล็อคในคลาสคุณลักษณะหลังจากสิ้นสุดความเข้าใจ


1
กำลังลบอะไร ไม่มีการอ้างอิงถึงวัตถุเคอร์เซอร์หลังจากความเข้าใจจบลงดังนั้นในทางทฤษฎีมันควรจะปิดลง การติดตั้งใช้งานของ ESRI นั้นเป็นไปตามที่คุณคาดหวังหรือไม่และฉันไม่คิดว่าเอกสารตอบคำถามนั้นจริงๆ
mikewatt
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.