plaintext = input("Please enter the text you want to compress")
filename = input("Please enter the desired filename")
with gzip.open(filename + ".gz", "wb") as outfile:
outfile.write(plaintext)
Приведенный выше код Python дает мне следующую ошибку:
Traceback (most recent call last):
File "C:/Users/Ankur Gupta/Desktop/Python_works/gzip_work1.py", line 33, in <module>
compress_string()
File "C:/Users/Ankur Gupta/Desktop/Python_works/gzip_work1.py", line 15, in compress_string
outfile.write(plaintext)
File "C:\Python32\lib\gzip.py", line 312, in write
self.crc = zlib.crc32(data, self.crc) & 0xffffffff
TypeError: 'str' does not support the buffer interface
Ответы:
Если вы используете Python3x, то
string
это не тот же тип, что и для Python 2.x, вы должны преобразовать его в байты (закодировать его).Также не используйте имена переменных, такие как
string
илиfile
когда они являются именами модулей или функций.РЕДАКТИРОВАТЬ @Tom
Да, не-ASCII текст также сжимается / распаковывается. Я использую польские буквы с кодировкой UTF-8:
источник
str
) и обратно не требуется , и существует риск декодирования ошибок или несоответствий между вводом и выводом.Существует более простое решение этой проблемы.
Вам просто нужно добавить
t
в режим, чтобы он сталwt
. Это заставляет Python открывать файл как текстовый файл, а не как двоичный файл. Тогда все будет просто работать.Полная программа становится такой:
источник
Вы не можете сериализовать строку Python 3 в байты без явного преобразования в некоторую кодировку.
возможно то, что вы хотите. Также это работает для Python 2.x и 3.x.
источник
Для Python 3.x вы можете конвертировать ваш текст в необработанные байты через:
Например:
Возвращенный объект будет работать с
outfile.write
.источник
Эта проблема обычно возникает при переключении с py2 на py3. В py2
plaintext
есть как строка, так и тип байтового массива . В py3plaintext
есть только строка , и методoutfile.write()
фактически принимает байтовый массив приoutfile
открытии в двоичном режиме, поэтому возникает исключение. Измените вход,plaintext.encode('utf-8')
чтобы решить проблему. Читайте дальше, если это вас беспокоит.В PY2, то декларация file.write сделал это , похоже , как вы прошли в строке:
file.write(str)
. На самом деле вы проходили в массив байтов, вы должны читали заявления вроде этого:file.write(bytes)
. Если вы читаете это , как это проблема проста,file.write(bytes)
нуждается в байтах типа и в PY3 , чтобы получить байты из ул конвертирование его:Почему py2 docs объявляет, что
file.write
взяла строку? Ну, в py2 различие между объявлениями не имело значения, потому что:У str- байтового класса py2 есть методы / конструкторы, которые в некоторых отношениях заставляют его вести себя как строковый класс, а в других - как класс байтового массива. Удобно для
file.write
не так ли?Почему py3 сломал эту замечательную систему? Ну, потому что в py2 основные строковые функции не работали для остального мира. Измерить длину слова с не-ASCII символом?
Все это время вы думали , что вы просили для Len строки в PY2, вы получаете длину массива байт из кодировки. Эта двусмысленность является фундаментальной проблемой для классов с двумя обязанностями. Какую версию любого вызова метода вы реализуете?
Хорошей новостью является то, что py3 решает эту проблему. Он распутывает классы str и bytes . Ул класс имеет нитевидные методы, отдельный байт класс имеет байты методов массива:
Надеюсь, знание этого поможет устранить проблему и немного облегчить перенос проблем с миграцией.
источник
Хорошо, если это полезно для вас в случае удаления раздражающего символа 'b'. Если у кого-то есть идея получше, пожалуйста, предложите мне или не стесняйтесь редактировать меня в любое время здесь. Я просто новичок
источник
s.encode('utf-8')
его настолько питонно, какs.decode('utf-8')
на заменуs = bytes("s", "utf-8")
Для
Django
вdjango.test.TestCase
модульном тестировании, я изменил мой python2 синтаксис:Чтобы использовать синтаксис Python3
.decode('utf8')
:источник