Anda menemukan masalah penyandian secara umum: Bagaimana saya bisa tahu di mana penyandian file?
Jawab: Anda tidak bisa kecuali format file yang disediakan untuk ini. XML, misalnya, dimulai dengan:
<?xml encoding="utf-8"?>
Header ini dipilih dengan hati-hati sehingga dapat dibaca terlepas dari pengodeannya. Dalam kasus Anda, tidak ada petunjuk seperti itu, maka editor atau Python Anda tidak tahu apa yang sedang terjadi. Oleh karena itu, Anda harus menggunakan codecs
modul dan menggunakan codecs.open(path,mode,encoding)
yang menyediakan bit yang hilang dengan Python.
Adapun editor Anda, Anda harus memeriksa apakah itu menawarkan beberapa cara untuk mengatur penyandian file.
Inti dari UTF-8 adalah untuk dapat menyandikan karakter 21-bit (Unicode) sebagai aliran data 8-bit (karena itulah satu-satunya hal yang dapat ditangani oleh semua komputer di dunia). Tetapi karena sebagian besar OS mendahului era Unicode, mereka tidak memiliki alat yang sesuai untuk melampirkan informasi pengkodean ke file pada hard disk.
Masalah selanjutnya adalah representasi dalam Python. Ini dijelaskan dengan sempurna dalam komentar oleh heikogerlach . Anda harus memahami bahwa konsol Anda hanya dapat menampilkan ASCII. Untuk menampilkan Unicode atau apa pun> = charcode 128, ia harus menggunakan beberapa cara untuk melarikan diri. Di editor Anda, Anda tidak boleh mengetikkan string tampilan lolos tetapi apa artinya string (dalam hal ini, Anda harus memasukkan umlaut dan menyimpan file).
Yang mengatakan, Anda bisa menggunakan fungsi Python eval () untuk mengubah string yang lolos menjadi string:
>>> x = eval("'Capit\\xc3\\xa1n\\n'")
>>> x
'Capit\xc3\xa1n\n'
>>> x[5]
'\xc3'
>>> len(x[5])
1
Seperti yang Anda lihat, string "\ xc3" telah berubah menjadi satu karakter. Ini sekarang merupakan string 8-bit, disandikan UTF-8. Untuk mendapatkan Unicode:
>>> x.decode('utf-8')
u'Capit\xe1n\n'
Gregg Lind bertanya: Saya pikir ada beberapa bagian yang hilang di sini: file f2 berisi: hex:
0000000: 4361 7069 745c 7863 335c 7861 316e Capit\xc3\xa1n
codecs.open('f2','rb', 'utf-8')
, misalnya, membaca semuanya dalam karakter yang terpisah (diharapkan) Apakah ada cara untuk menulis ke file di ASCII yang akan berfungsi?
Jawaban: Itu tergantung pada apa yang Anda maksud. ASCII tidak dapat mewakili karakter> 127. Jadi, Anda perlu cara untuk mengatakan "beberapa karakter berikutnya berarti sesuatu yang istimewa" yang dilakukan oleh urutan "\ x". Dikatakan: Dua karakter berikutnya adalah kode dari satu karakter. "\ u" melakukan hal yang sama menggunakan empat karakter untuk menyandikan Unicode hingga 0xFFFF (65535).
Jadi, Anda tidak dapat langsung menulis Unicode ke ASCII (karena ASCII tidak mengandung karakter yang sama). Anda dapat menulisnya saat string keluar (seperti pada f2); dalam hal ini, file dapat direpresentasikan sebagai ASCII. Atau Anda dapat menulisnya sebagai UTF-8, dalam hal ini, Anda memerlukan aliran aman 8-bit.
Solusi Anda menggunakan decode('string-escape')
tidak berfungsi, tetapi Anda harus menyadari berapa banyak memori yang Anda gunakan: Tiga kali jumlah penggunaan codecs.open()
.
Ingat bahwa file hanya urutan byte dengan 8 bit. Baik bit maupun byte tidak memiliki arti. Kaulah yang mengatakan "65 berarti 'A'". Karena \xc3\xa1
harus menjadi "à" tetapi komputer tidak memiliki sarana untuk mengetahuinya, Anda harus mengetahuinya dengan menentukan pengkodean yang digunakan saat menulis file.