Jika Anda membaca seluruh file dengan content = open('Path/to/file', 'r').read()
apakah pegangan file dibiarkan terbuka sampai skrip keluar? Apakah ada metode yang lebih ringkas untuk membaca seluruh file?
Jika Anda membaca seluruh file dengan content = open('Path/to/file', 'r').read()
apakah pegangan file dibiarkan terbuka sampai skrip keluar? Apakah ada metode yang lebih ringkas untuk membaca seluruh file?
Jawaban atas pertanyaan itu agak tergantung pada implementasi Python tertentu.
Untuk memahami semua ini, berikan perhatian khusus pada file
objek yang sebenarnya . Dalam kode Anda, objek itu disebutkan hanya sekali, dalam ekspresi, dan menjadi tidak dapat diakses segera setelah read()
panggilan kembali.
Ini berarti bahwa objek file adalah sampah. Satu-satunya pertanyaan yang tersisa adalah "Kapan pemungut sampah mengumpulkan objek file?".
dalam CPython, yang menggunakan penghitung referensi, jenis sampah ini langsung diperhatikan, dan karenanya akan segera dikumpulkan. Ini biasanya tidak berlaku untuk implementasi python lainnya.
Solusi yang lebih baik, untuk memastikan bahwa file ditutup, adalah pola ini:
with open('Path/to/file', 'r') as content_file:
content = content_file.read()
yang akan selalu menutup file segera setelah blok berakhir; bahkan jika pengecualian terjadi.
Sunting: Untuk memberikan poin yang lebih baik:
Selain file.__exit__()
, yang "secara otomatis" dipanggil dalam with
pengaturan manajer konteks, satu-satunya cara lain yang file.close()
secara otomatis dipanggil (yaitu, selain secara eksplisit menyebutnya sendiri,) adalah melalui file.__del__()
. Ini membawa kita pada pertanyaan kapan __del__()
dipanggil?
Program yang ditulis dengan benar tidak dapat mengasumsikan bahwa finalis akan pernah berjalan pada titik mana pun sebelum penghentian program.
- https://devblogs.microsoft.com/oldnewthing/20100809-00/?p=13203
Khususnya:
Objek tidak pernah secara eksplisit dihancurkan; Namun, ketika mereka menjadi tidak terjangkau mereka mungkin menjadi sampah. Suatu implementasi diperbolehkan untuk menunda pengumpulan sampah atau menghilangkannya sama sekali - ini adalah masalah kualitas implementasi bagaimana pengumpulan sampah dilaksanakan, selama tidak ada benda yang dikumpulkan yang masih dapat dijangkau.
[...]
CPython saat ini menggunakan skema penghitungan referensi dengan deteksi (opsional) yang tertunda terhadap sampah yang terhubung secara siklikal, yang mengumpulkan sebagian besar objek segera setelah mereka menjadi tidak terjangkau, tetapi tidak dijamin untuk mengumpulkan sampah yang mengandung referensi melingkar.
- https://docs.python.org/3.5/reference/datamodel.html#objects-values-and-types
(Penekanan milikku)
tetapi seperti yang disarankan, implementasi lain mungkin memiliki perilaku lain. Sebagai contoh, PyPy memiliki 6 implementasi pengumpulan sampah yang berbeda !
__exit__()
dalam kasus seperti itu terdengar seperti cacat desain.try
/finally
menjadi fiddly dan sangat berguna bagi petugas kebersihan yangwith
memecahkan masalah. Perbedaan antara "menutup secara eksplisit" dan "mengelola denganwith
" adalah bahwa penangan keluar dipanggil meskipun ada pengecualian. Anda bisa memasukkannya keclose()
dalamfinally
klausa, tetapi itu tidak jauh berbeda dengan menggunakanwith
, sedikit lebih berantakan (3 baris tambahan, bukan 1), dan sedikit lebih sulit untuk membuatnya dengan benar.with foo() as f: [...]
pada dasarnya adalah samaf = foo()
,f.__enter__()
, [...] danf.__exit__()
dengan pengecualian ditangani , sehingga__exit__
selalu disebut. Jadi file selalu ditutup.Anda dapat menggunakan pathlib .
Untuk Python 3.5 dan lebih tinggi:
Untuk versi Python yang lebih lama, gunakan pathlib2 :
Kemudian:
Ini adalah
read_text
implementasi aktual :sumber
Nah, jika Anda harus membaca file baris demi baris agar bisa bekerja dengan setiap baris, Anda bisa menggunakannya
Atau bahkan cara yang lebih baik:
sumber
Alih-alih mengambil konten file sebagai string tunggal, mungkin berguna untuk menyimpan konten sebagai daftar semua baris yang terdiri dari file :
Seperti yang bisa dilihat, kita perlu menambahkan metode gabungan
.strip().split("\n")
ke jawaban utama di utas ini .Di sini,
.strip()
cukup hapus spasi putih dan karakter baris baru di akhir seluruh string file, dan.split("\n")
buat daftar aktual melalui pemisahan seluruh string file di setiap karakter baris baru \ n .Selain itu, dengan cara ini seluruh konten file dapat disimpan dalam variabel, yang mungkin diinginkan dalam beberapa kasus, alih-alih mengulangi file baris demi baris seperti yang ditunjukkan dalam jawaban sebelumnya .
sumber