Jika yang terbaik adalah membuka kursor menggunakan pernyataan with untuk memastikan itu dihapus, seperti:
with arcpy.da.UpdateCursor(fc,fields) as cursor:
Kemudian, jika kursor digunakan sebagai iterable dalam pemahaman seperti:
d = {k:v for (k,v) in arcpy.da.SearchCursor(fc,fields)}
Apakah perlu untuk menghapus kursor setelah menggunakannya dalam pemahaman?
da
kursor baru : sgillies.net/2011/02/01/get-with-it.html dan help.arcgis.com/ id / arcgisdesktop / 10.0 / help / index.html # //… . Secara khusus, lihat komentar @JasonScheirer di bagian bawah tautan pertama.Jawaban:
Apakah itu mutlak diperlukan adalah pertanyaan yang salah untuk ditanyakan. Pertanyaannya adalah apakah itu ide yang bagus.
Sebagai aturan dalam pemrograman, Anda harus menghindari melakukan hal-hal aneh dan menggunakan alat terbaik untuk pekerjaan itu . Jika sesuatu memiliki cara eksplisit untuk melepaskan sumber daya, cukup buat rilis itu eksplisit dan lakukan dengan itu:
Apa yang mungkin tidak Anda sadari adalah bahwa
with
klausa sebenarnya memunculkan logika tambahan. Sebuahwith
klausul membutuhkan manajer konteks, yang harus memiliki__enter__
(dipanggil saat blok dimasukkan) dan__exit__
(dipanggil saat blok tersebut keluar) metode. Secara khusus,__exit__
metode ini dipanggil terlepas dari apakah pengecualian terjadi, memastikan program selalu melepaskan sumber daya meskipun ada kesalahan. Ini memberikan kode Anda dokumentasi eksplisit tentang kapan sumber daya diperoleh dan kapan dirilis, dan memastikan bahwa sumber daya dapat dirilis sesegera mungkin.Sebaliknya, Anda tidak dapat benar-benar bergantung pada runtime untuk segera menutupnya secara ajaib untuk Anda. Ini karena cara itu ditutup adalah dengan memanggil destruktor objek, yang mungkin atau mungkin tidak terjadi segera. Python tidak membuat jaminan tentang kapan sebuah destructor dipanggil, hanya saja pada akhirnya ketika objek tersebut adalah sampah yang dikumpulkan. (Lihat di sini .) Saat ini, Python diimplementasikan sehingga terjadi segera setelah tidak ada lagi referensi ke objek. Tetapi mudah untuk secara tidak sengaja menyebarkan referensi ke suatu objek, dan runtime Python mungkin berubah.
Juga pertimbangkan perawatan jangka panjang. Tidak ada referensi jangka panjang untuk sekarang, tetapi apa yang terjadi di 6 bulan ketika Anda perlu memodifikasi kode sehingga ada adalah referensi? Bagaimana jika orang lain melakukannya? Orang yang membuat perubahan mungkin tidak berpikir untuk beralih ke
with
blok karena tidak ada yang sudah ada di sana. Membuat membersihkan sumber daya Anda kebiasaan , dan Anda akan memiliki lebih sedikit masalah dengan itu.Apakah Anda benar-benar ingin mengikat kode Anda ke detail implementasi pengumpulan sampah? Apakah Anda ingin terus-menerus memikirkan apakah Anda mungkin secara tidak sengaja menyebarkan referensi melalui pengecualian? Tidak, tidak. Bayangkan jika itu terjadi ketika skrip dipanggil di ArcMap. Pengguna akan dipaksa untuk menutup seluruh proses hanya untuk melepaskan file. Jadi jangan menempatkan diri Anda pada posisi itu. Lepaskan sumber daya secara eksplisit. Menyimpan satu baris kode tidak sebanding dengan risiko masalah yang diakibatkannya. Manajer konteks adalah mekanisme standar untuk memperoleh dan melepaskan sumber daya dengan Python, dan mereka melakukannya dengan sangat baik.
Intinya adalah bahwa tidak merilisnya secara eksplisit adalah ide yang buruk.
Ini, tentu saja, mengasumsikan bahwa kode tersebut memiliki kemungkinan mempengaruhi orang lain, seperti memasukkannya ke dalam skrip yang harus dijalankan atau dikelola orang lain atau mungkin menunda penyerahan pekerjaan Anda jika Anda harus menutup ArcMap sepenuhnya karena Anda tidak dapat menyimpan perubahan Anda. Jika Anda satu-satunya yang akan terkena dampak masalah, maka dengan segala cara, terbanglah di hadapan praktik-praktik baik yang Anda inginkan.
sumber
Tidak, tidak perlu menghapus
cursor
setelah menggunakannya dalam pemahaman. Acursor
adalah turunan dari kelas, yang merupakan objek (semua yang ada di python adalah objek). Setiap sesi python memilikinamespace
yang berisi referensi ke semua objek dalam sesi - anggap saja seperti kamus di mana kunci adalah referensi untuk setiap objek, dan nilainya adalah objek itu sendiri. Ketika 'jumlah referensi' - jumlah kunci yang merujuk ke objek itu - turun ke nol, objek dihapus dan memori dialokasikan kembali . Saat Anda menggunakancursor
dalam pemahaman, tidak ada referensi ke objek di namespace. Setelah pemahaman selesai, objek akan dihapus.Tidak ada entri di namespace, dan karenanya tidak perlu menghapus apa pun. ESRI juga menggambarkan sintaks ini dalam contoh 2, di sini .
Untuk lebih memperjelas, jika Anda menjalankan:
Anda akan melihat file .lock muncul di direktori (periksa file explorer Anda). Referensi kursor adalah
a
, yang akan membuatcursor
(dan karena itu kunci) bertahan hinggaa
dihapus. Jadi saat Anda menjalankan:Entri di namespace akan dihapus, dan kunci akan dirilis (file .lock akan hilang). Jika Anda menjalankan:
Anda juga tidak akan melihat file kunci, atau itu akan hilang ketika perintah selesai. Tanpa entri di namespace,
cursor
tidak persisten.t
merujuk ke daftar yang baru saja Anda buat, bukan yangcursor
digunakan untuk membuatnya.Untuk meringkas, Anda hanya perlu khawatir tentang menghapus
cursors
ketika mereka memiliki referensi di namespace (yaitu ketika Anda telah menetapkan mereka ke variabel, sepertia
pada contoh di atas).sumber
Mengunci dengan kursor arcpy.da hampir sama dengan mengunci dengan kursor arcpy asli.
Setelah menguji kode Anda, dan seperti yang ditunjukkan gberard, tidak ada referensi ke kursor setelah pemahaman berakhir.
Juga, tidak ada kunci pada kelas fitur setelah pemahaman berakhir.
sumber