Untuk menjawab pertanyaan Anda secara langsung:Saya tidak melihat ada salahnya menutup di akhir with
memblokir. Saya tidak bisa mengatakan mengapa hal itu tidak dilakukan dalam kasus ini. Tetapi, karena ada kelangkaan aktivitas pada pertanyaan ini, saya telah menelusuri riwayat kode dan akan memberikan beberapa pemikiran (tebakan ) mengapa close()
mungkin tidak dipanggil:
-
Ada kemungkinan kecil bahwa memutar panggilan ke
nextset()
mungkin melemparkan pengecualian - mungkin ini telah diamati dan dilihat sebagai tidak diinginkan. Ini mungkin mengapa versicursors.py
berisi struktur ini diclose()
:def close(self): """Close the cursor. No further queries will be possible.""" if not self.connection: return self._flush() try: while self.nextset(): pass except: pass self.connection = None
-
Ada potensi (agak jauh) bahwa mungkin perlu beberapa saat untuk memutar semua hasil yang tersisa tanpa melakukan apa-apa. Oleh karena itu
close()
mungkin tidak dipanggil untuk menghindari melakukan beberapa iterasi yang tidak perlu. Apakah Anda pikir itu layak untuk menyimpan siklus jam itu subjektif, saya kira, tetapi Anda bisa berdebat di sepanjang baris "jika tidak perlu, jangan lakukan". -
Menjelajahi komit sourceforge, fungsionalitas ditambahkan ke bagasi oleh komit ini pada tahun 2007 dan tampaknya bagian
connections.py
. ini tidak berubah sejak. Itu adalah gabungan berdasarkan komit ini , yang memiliki pesanDan kode yang Anda kutip tidak pernah berubah sejak saat itu.
Ini mendorong pemikiran terakhir saya - ini mungkin hanya upaya/prototipe pertama yang baru saja berhasil dan karenanya tidak pernah berubah.
Versi yang lebih modern
Anda menautkan ke sumber untuk konektor versi lama. Saya perhatikan ada garpu yang lebih aktif dari perpustakaan yang sama di sini , yang saya tautkan di komentar saya tentang "versi yang lebih baru" di poin 1.
Perhatikan bahwa versi yang lebih baru dari modul ini telah mengimplementasikan __enter__()
dan __exit__()
dalam cursor
sendiri:lihat di sini
. __exit__()
di sini tidak panggil self.close()
dan mungkin ini menyediakan cara yang lebih standar untuk menggunakan sintaks with mis.
with conn.cursor() as c:
#Do your thing with the cursor
Catatan akhir
N.B. Saya kira saya harus menambahkan, sejauh yang saya mengerti pengumpulan sampah (bukan ahli juga) setelah tidak ada referensi ke conn
, itu akan dialokasikan. Pada titik ini tidak akan ada referensi ke objek kursor dan itu akan dibatalkan alokasinya juga.
Namun memanggil cursor.close()
tidak berarti bahwa itu akan menjadi sampah yang dikumpulkan. Itu hanya membakar melalui hasil dan mengatur koneksi ke None
. Ini berarti tidak dapat digunakan kembali, tetapi tidak akan langsung menjadi sampah yang dikumpulkan. Anda dapat meyakinkan diri sendiri tentang hal itu dengan memanggil cursor.close()
. secara manual setelah with
blok dan kemudian, katakanlah, mencetak beberapa atribut cursor
N.B. 2 Saya pikir ini adalah penggunaan with
yang agak tidak biasa sintaks sebagai conn
objek tetap ada karena sudah berada di lingkup luar - tidak seperti, katakanlah, with open('filename') as f:
di mana tidak ada objek yang berkeliaran dengan referensi setelah akhir with
blokir.