Dalam Python, jika Anda membuka file tanpa memanggil close()
, atau menutup file tetapi tidak menggunakan try
- finally
" with
" pernyataan, apakah ini masalah? Atau apakah cukup sebagai praktik pengkodean untuk mengandalkan pengumpulan sampah Python untuk menutup semua file? Sebagai contoh, jika seseorang melakukan ini:
for line in open("filename"):
# ... do stuff ...
... apakah ini masalah karena file tidak pernah dapat ditutup dan pengecualian dapat terjadi yang mencegahnya tidak ditutup? Atau pasti akan ditutup pada akhir for
pernyataan karena file keluar dari ruang lingkup?
python
file
garbage-collection
pengguna553702
sumber
sumber
for
blok. Jumlah referensi akan menjadi nol, menyebabkannya ditutup secara otomatis, tetapi hanya fungsi, kelas, dan modul yang mendefinisikan cakupan dalam Python, bukan pernyataan majemuk lainnya.for
blok dan fungsi / kelas / modul. Ini jauh lebih sederhana dari itu: objek tidak memiliki cakupan, hanya nama yang melakukannya. Tidak ada nama yang merujuk ke objek ini, jadi tidak ada apa pun di sini untuk tetap berada dalam ruang lingkup atau keluar dari ruang lingkup.for
loop, dan menyebutkan bahwa file ditutup karena alasan yang sama sekali berbeda. Itu tidak masuk ke lingkup apa yang ada di Python, karena itu tidak relevan di sini.Jawaban:
Dalam contoh Anda file tidak dijamin akan ditutup sebelum juru bahasa keluar. Dalam versi CPython saat ini, file akan ditutup pada akhir for for loop karena CPython menggunakan penghitungan referensi sebagai mekanisme pengumpulan sampah utamanya, tetapi itu adalah detail implementasi, bukan fitur bahasa. Implementasi lain dari Python tidak dijamin bekerja dengan cara ini. Misalnya IronPython, PyPy, dan Jython tidak menggunakan penghitungan referensi dan karenanya tidak akan menutup file di akhir loop.
Ini praktik yang buruk untuk mengandalkan implementasi pengumpulan sampah CPython karena membuat kode Anda kurang portabel. Anda mungkin tidak memiliki kebocoran sumber daya jika Anda menggunakan CPython, tetapi jika Anda pernah beralih ke implementasi Python yang tidak menggunakan penghitungan referensi Anda harus melalui semua kode Anda dan memastikan semua file Anda ditutup dengan benar.
Untuk contoh Anda gunakan:
sumber
with open() as f
secara otomatis menutup file setelah selesai?with
disediakan oleh pernyataan itu, tetapi tentu saja agar sihir ini bekerja, objek harus memiliki metode utama__enter__
dan__exit__
, yang terakhir objek melakukanclose
dan hal-hal pembersihan lainnya yang perlu dilakukan di akhirwith
pernyataan ...Beberapa Python akan menutup file secara otomatis ketika mereka tidak lagi direferensikan, sementara yang lain tidak akan dan itu tergantung pada O / S untuk menutup file ketika interpreter Python keluar.
Bahkan untuk Python yang akan menutup file untuk Anda, waktunya tidak dijamin: itu bisa segera, atau bisa detik / menit / jam / hari kemudian.
Jadi, sementara Anda mungkin tidak mengalami masalah dengan Python yang Anda gunakan, sudah pasti bukan praktik yang baik untuk membiarkan file Anda tetap terbuka. Bahkan, di cpython 3 Anda sekarang akan mendapatkan peringatan bahwa sistem harus menutup file untuk Anda jika Anda tidak melakukannya.
Moral: Bersihkan dirimu. :)
sumber
Meskipun cukup aman untuk menggunakan konstruksi seperti itu dalam kasus khusus ini, ada beberapa peringatan untuk generalisasi praktik seperti itu:
sumber
File tidak mendapatkan sampah yang dikumpulkan, dan karenanya ditutup. GC menentukan kapan ditutup, bukan Anda. Jelas, ini bukan praktik yang disarankan karena Anda mungkin menekan batas pegangan file terbuka jika Anda tidak menutup file segera setelah Anda selesai menggunakannya. Bagaimana jika dalam
for
lingkaran Anda, Anda membuka lebih banyak file dan membiarkannya tetap?sumber
for
pernyataan - Anda tidak perlu menunggu untuk menjalankan pengumpulan sampah berikutnya.Hai Sangat penting untuk menutup deskriptor file Anda dalam situasi ketika Anda akan menggunakan konten itu dalam skrip python yang sama. Saya hari ini sendiri menyadari setelah debugging begitu lama. Alasannya adalah konten akan diedit / dihapus / disimpan hanya setelah Anda menutup Anda deskriptor file dan perubahan terpengaruh ke file!
Jadi misalkan Anda memiliki situasi ketika Anda menulis konten ke file baru dan kemudian tanpa menutup fd Anda menggunakan file itu (bukan fd) dalam perintah shell lain yang membaca kontennya. Dalam situasi ini Anda tidak akan mendapatkan konten untuk perintah shell seperti yang diharapkan dan jika Anda mencoba untuk debug Anda tidak dapat menemukan bug dengan mudah. Anda juga dapat membaca lebih lanjut di entri blog saya http://magnificentzps.blogspot.in/2014/04/importance-of-closing-file-descriptor.html
sumber
Selama proses I / O, data di-buffer: ini berarti disimpan di lokasi sementara sebelum ditulis ke file.
Python tidak menyiram buffer — yaitu, menulis data ke file — hingga yakin Anda selesai menulis. Salah satu cara untuk melakukan ini adalah dengan menutup file.
Jika Anda menulis ke file tanpa menutup, data tidak akan membuatnya ke file target.
sumber