Ada dua cara untuk membuka file teks dengan Python:
f = open(filename)
Dan
import codecs
f = codecs.open(filename, encoding="utf-8")
Kapan codecs.openlebih disukai open?
Ada dua cara untuk membuka file teks dengan Python:
f = open(filename)
Dan
import codecs
f = codecs.open(filename, encoding="utf-8")
Kapan codecs.openlebih disukai open?
Jawaban:
Sejak Python 2.6, praktik yang baik adalah menggunakan io.open() , yang juga membutuhkan encodingargumen, seperti yang sekarang sudah usang codecs.open(). Di Python 3, io.openadalah alias untuk bawaan open(). Jadi io.open()bekerja dengan Python 2.6 dan semua versi yang lebih baru, termasuk Python 3.4. Lihat dokumen: http://docs.python.org/3.4/library/io.html
Sekarang, untuk pertanyaan awal: saat membaca teks (termasuk "teks biasa", HTML, XML dan JSON) di Python 2 Anda harus selalu menggunakan io.open()dengan pengkodean eksplisit, atau open()dengan pengkodean eksplisit di Python 3. Melakukan itu berarti Anda mendapatkan dengan benar mendekode Unicode, atau langsung mendapatkan kesalahan, membuatnya lebih mudah untuk di-debug.
"Teks biasa" ASCII murni adalah mitos dari masa lalu. Teks bahasa Inggris yang tepat menggunakan tanda kutip keriting, tanda pisah em, peluru, € (tanda euro) dan bahkan diaeresis (¨). Jangan naif! (Dan jangan lupakan pola desain Façade!)
Karena ASCII murni bukanlah pilihan nyata, open()tanpa pengkodean eksplisit hanya berguna untuk membaca file biner .
io.open()untuk teks, dan open()hanya untuk biner. Implikasinya adalah hal codecs.open()itu sama sekali tidak disukai.
opendan codecs.open, dan secara khusus kapan yang terakhir lebih disukai daripada yang pertama. Sebuah jawaban yang tidak terlalu disebutkan codecs.opentidak dapat menjawab pertanyaan itu.
codecs.open()benar untuk digunakan) maka tidak ada jawaban yang "benar" tentang kapan harus menggunakannya. Jawabannya adalah dengan menggunakan io.open(). Ini seperti jika saya bertanya "kapan saya harus menggunakan kunci inggris untuk menancapkan paku ke dinding?". Jawaban yang benar adalah "gunakan palu".
Secara pribadi, saya selalu menggunakan codecs.openkecuali ada kebutuhan teridentifikasi yang jelas untuk digunakan open**. Alasannya adalah bahwa saya sering digigit karena input utf-8 menyelinap ke dalam program saya. "Oh, saya hanya tahu itu akan selalu ascii" cenderung menjadi asumsi yang sering rusak.
Dengan asumsi 'utf-8' sebagai pengkodean default cenderung menjadi pilihan default yang lebih aman menurut pengalaman saya, karena ASCII dapat diperlakukan sebagai UTF-8, tetapi kebalikannya tidak benar. Dan dalam kasus-kasus ketika saya benar-benar tahu bahwa inputnya adalah ASCII, maka saya masih melakukan codecs.openkarena saya sangat percaya pada "eksplisit lebih baik daripada implisit" .
** - dengan Python 2.x, karena komentar pada pertanyaan yang dinyatakan dengan Python 3 openmenggantikancodecs.open
openkadang - kadang dapat menangani dengan baik karakter non-latin yang dikodekan UTF-8 dari set unicode, dan terkadang gagal total ...
io.opentidak mengambil parameter pengkodean dari apa yang saya lihat di python 2.7.5
io.openmenerima encodingdan newlineparameter dan menafsirkannya seperti yang dilakukan Python 3. Tidak seperti codecs.open, file yang dibuka dengan io.openakan memunculkan TypeError: write() argument 1 must be unicode, not strbahkan dengan Python 2.7 jika Anda mencoba untuk menulis str( bytes) padanya. File yang dibuka dengan codecs.opensebaliknya akan mencoba konversi implisit ke unicode, yang sering kali menyebabkan kebingungan UnicodeDecodeError.
Di Python 2 ada string unicode dan bytestrings. Jika Anda hanya menggunakan bytestrings, Anda dapat membaca / menulis ke file yang dibuka dengan open()baik. Bagaimanapun, string hanyalah byte.
Masalahnya muncul ketika, katakanlah, Anda memiliki string unicode dan Anda melakukan hal berikut:
>>> example = u'Μου αρέσει Ελληνικά'
>>> open('sample.txt', 'w').write(example)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
UnicodeEncodeError: 'ascii' codec can't encode characters in position 0-2: ordinal not in range(128)
Jadi di sini jelas Anda secara eksplisit menyandikan string unicode Anda di utf-8 atau Anda gunakan codecs.openuntuk melakukannya untuk Anda secara transparan.
Jika Anda hanya pernah menggunakan bytestrings maka tidak ada masalah:
>>> example = 'Μου αρέσει Ελληνικά'
>>> open('sample.txt', 'w').write(example)
>>>
Ini menjadi lebih terlibat daripada ini karena ketika Anda menggabungkan string unicode dan bytestring dengan +operator, Anda mendapatkan string unicode. Mudah digigit oleh yang satu itu.
Juga codecs.opentidak suka bytestring dengan karakter non-ASCII yang diteruskan:
codecs.open('test', 'w', encoding='utf-8').write('Μου αρέσει')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/usr/lib/python2.7/codecs.py", line 691, in write
return self.writer.write(data)
File "/usr/lib/python2.7/codecs.py", line 351, in write
data, consumed = self.encode(object, self.errors)
UnicodeDecodeError: 'ascii' codec can't decode byte 0xce in position 0: ordinal not in range(128)
Saran tentang string untuk input / output biasanya "diubah ke unicode sedini mungkin dan kembali ke bytestring selambat mungkin". Menggunakan codecs.openmemungkinkan Anda melakukan yang terakhir dengan sangat mudah.
Berhati-hatilah karena Anda memberikan string unicode dan bukan bytestring yang mungkin memiliki karakter non-ASCII.
u''di contoh pertama. Ini berarti saya membuat string unicode, bukan bytestring. Inilah perbedaan antara kedua contoh tersebut. Pada contoh kedua saya membuat bytestring dan menulis salah satunya ke file sudah cukup. String unicode tidak baik jika Anda menggunakan karakter di luar ASCII.
codecs.open, saya kira, hanyalah sisa dari Python 2hari - hari ketika open-in open memiliki antarmuka yang jauh lebih sederhana dan kemampuan yang lebih sedikit. Di Python 2, built-in opentidak mengambil argumen encoding, jadi jika Anda ingin menggunakan sesuatu selain mode biner atau encoding default, codecs.open seharusnya digunakan.
Masuk Python 2.6, modul io membantu untuk membuat segalanya lebih sederhana. Menurut dokumentasi resmi
New in version 2.6.
The io module provides the Python interfaces to stream handling.
Under Python 2.x, this is proposed as an alternative to the
built-in file object, but in Python 3.x it is the default
interface to access files and streams.
Karena itu, satu-satunya penggunaan yang dapat saya pikirkan codecs.opendalam skenario saat ini adalah untuk kompatibilitas ke belakang. Dalam semua skenario lain (kecuali Anda menggunakan Python <2.6) lebih baik digunakan io.open. Juga di Python 3.x io.opensama denganbuilt-in open
catatan:
Ada perbedaan sintaksis antara codecs.opendan io.openjuga.
codecs.open:
open(filename, mode='rb', encoding=None, errors='strict', buffering=1)
io.open:
open(file, mode='r', buffering=-1, encoding=None,
errors=None, newline=None, closefd=True, opener=None)
codecs.opendan io.openberbeda dalam hal sintaks, mereka mengembalikan objek dari tipe yang berbeda. Juga codecs.openselalu bekerja dengan file dalam mode biner.
Saat Anda ingin memuat file biner, gunakan
f = io.open(filename, 'b').
Untuk membuka file teks, selalu gunakan f = io.open(filename, encoding='utf-8')dengan encoding eksplisit.
Dalam python 3 namun openmelakukan hal yang sama seperti io.opendan dapat digunakan sebagai pengganti.
Catatan:
codecs.opendirencanakan untuk ditinggalkan dan digantiio.opensetelah diperkenalkan di python 2.6 . Saya hanya akan menggunakannya jika kode harus kompatibel dengan versi python sebelumnya. Untuk informasi lebih lanjut tentang codec dan unicode dengan python, lihat Unicode HOWTO .
io.openatau codecs.open? 2. codecs.openbelum usang, baca diskusi di halaman yang Anda tautkan.
Saat Anda bekerja dengan file teks dan ingin encoding dan decoding transparan menjadi objek Unicode.
Saya berada dalam situasi untuk membuka file .asm dan memproses file.
#https://docs.python.org/3/library/codecs.html#codecs.ignore_errors
#https://docs.python.org/3/library/codecs.html#codecs.Codec.encode
with codecs.open(file, encoding='cp1252', errors ='replace') as file:
Tanpa banyak masalah saya bisa membaca seluruh file, ada saran?
codecs.open()dalam 3.x sudah usang, karenaopen()mendapatkanencodingargumen.