Masalah ini umumnya terjadi ketika beralih dari py2 ke py3. Dalam py2 plaintext
adalah tipe string dan byte byte . Dalam py3 plaintext
hanya sebuah string , dan metode ini outfile.write()
benar-benar mengambil array byte saat outfile
dibuka dalam mode biner, jadi pengecualian dimunculkan. Ubah input keplaintext.encode('utf-8')
untuk memperbaiki masalah. Baca terus jika ini mengganggu Anda.
Dalam py2, yang deklarasi file.write membuatnya tampak seperti Anda melewati dalam sebuah string: file.write(str)
. Sebenarnya Anda lewat di array byte, Anda seharusnya membaca deklarasi seperti ini: file.write(bytes)
. Jika Anda membacanya seperti ini masalahnya sederhana, file.write(bytes)
perlu tipe byte dan di py3 untuk mendapatkan byte dari str Anda mengubahnya:
py3>> outfile.write(plaintext.encode('utf-8'))
Mengapa dokumen py2 menyatakan file.write
mengambil string? Nah di py2 perbedaan deklarasi tidak masalah karena:
py2>> str==bytes #str and bytes aliased a single hybrid class in py2
True
Kelas str-bytes py2 memiliki metode / konstruktor yang membuatnya berperilaku seperti kelas string dalam beberapa hal dan kelas array byte di orang lain. Nyaman file.write
bukan ?:
py2>> plaintext='my string literal'
py2>> type(plaintext)
str #is it a string or is it a byte array? it's both!
py2>> outfile.write(plaintext) #can use plaintext as a byte array
Mengapa py3 merusak sistem yang bagus ini? Nah karena dalam fungsi string dasar py2 tidak bekerja untuk seluruh dunia. Mengukur panjang kata dengan karakter non-ASCII?
py2>> len('¡no') #length of string=3, length of UTF-8 byte array=4, since with variable len encoding the non-ASCII chars = 2-6 bytes
4 #always gives bytes.len not str.len
Selama ini Anda mengira Anda meminta len dari string di py2, Anda mendapatkan panjang byte array dari pengkodean. Ambiguitas itu adalah masalah mendasar dengan kelas tugas ganda. Versi panggilan metode apa saja yang Anda terapkan?
Kabar baiknya adalah bahwa py3 memperbaiki masalah ini. Ini menguraikan kelas str dan byte . Kelas str memiliki metode seperti string, kelas byte yang terpisah memiliki metode array byte:
py3>> len('¡ok') #string
3
py3>> len('¡ok'.encode('utf-8')) #bytes
4
Semoga mengetahui hal ini membantu menghilangkan misteri masalah, dan membuat rasa sakit migrasi sedikit lebih mudah untuk ditanggung.