Эта проблема обычно возникает при переключении с py2 на py3. В py2 plaintext
есть как строка, так и тип байтового массива . В py3 plaintext
есть только строка , и метод outfile.write()
фактически принимает байтовый массив при outfile
открытии в двоичном режиме, поэтому возникает исключение. Измените вход, plaintext.encode('utf-8')
чтобы решить проблему. Читайте дальше, если это вас беспокоит.
В PY2, то декларация file.write сделал это , похоже , как вы прошли в строке: file.write(str)
. На самом деле вы проходили в массив байтов, вы должны читали заявления вроде этого: file.write(bytes)
. Если вы читаете это , как это проблема проста, file.write(bytes)
нуждается в байтах типа и в PY3 , чтобы получить байты из ул конвертирование его:
py3>> outfile.write(plaintext.encode('utf-8'))
Почему py2 docs объявляет, что file.write
взяла строку? Ну, в py2 различие между объявлениями не имело значения, потому что:
py2>> str==bytes #str and bytes aliased a single hybrid class in py2
True
У str- байтового класса py2 есть методы / конструкторы, которые в некоторых отношениях заставляют его вести себя как строковый класс, а в других - как класс байтового массива. Удобно для file.write
не так ли?
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
Почему py3 сломал эту замечательную систему? Ну, потому что в py2 основные строковые функции не работали для остального мира. Измерить длину слова с не-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
Все это время вы думали , что вы просили для Len строки в PY2, вы получаете длину массива байт из кодировки. Эта двусмысленность является фундаментальной проблемой для классов с двумя обязанностями. Какую версию любого вызова метода вы реализуете?
Хорошей новостью является то, что py3 решает эту проблему. Он распутывает классы str и bytes . Ул класс имеет нитевидные методы, отдельный байт класс имеет байты методов массива:
py3>> len('¡ok') #string
3
py3>> len('¡ok'.encode('utf-8')) #bytes
4
Надеюсь, знание этого поможет устранить проблему и немного облегчить перенос проблем с миграцией.