2017-01-22 6 views
2

У меня есть рудиментарное понимание python, но я не понимаю, как обращаться с проблемами двоичного кодирования. Я пытаюсь запустить образец кода из примера firefox-webextensions, в котором скрипт python отправляет текст, который читается программой javascript. Я продолжаю сталкиваться с ошибками кодирования.Кодировка: TypeError: write() аргумент должен быть str, а не байтами

Код питон:

#! /Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5 
import sys, json, struct 

text = "pong" 

encodedContent = json.dumps(text) 
encodedLength = struct.pack('@I', len(encodedContent)) 
encodedMessage = {'length': encodedLength, 'content': encodedContent} 

sys.stdout.write(encodedMessage['length']) 
sys.stdout.write(encodedMessage['content']) 

Трассировка ошибки (отображается в консоли FireFox) является:

stderr output from native app chatX: Traceback (most recent call last): 
stderr output from native app chatX: File "/Users/inchem/Documents/firefox addons/py/chatX.py", line 10, in <module> 
stderr output from native app chatX: sys.stdout.write(encodedMessage['length']) 
stderr output from native app chatX: TypeError: write() argument must be str, not bytes 

Запуск питона 3.5.1 на OS X El Capitan 10.11.6, x86 64bit ЦПУ; светлячок разработчик эд 52,0

Питон скрипт я использую, как показано выше, сводится к минимуму с оригинала на https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Native_messaging

Я также попытался:

sys.stdout.buffer.write(encodedMessage['length']) 
sys.stdout.buffer.write(encodedMessage['content']) 

который генерировал:

stderr output from native app chatX: sys.stdout.buffer.write(encodedMessage['content']) 
stderr output from native app chatX: TypeError: a bytes-like object is required, not 'str'  
+0

вы пытались преобразовать его в строку как следующий? Sys.stdout.buffer.write (ул (encodedMessage [ «длина»])) – Shiping

ответ

3

Пример был, вероятно, совместим с Python 2, но в Python все изменилось.

Вы генерируете бинарное представление длины в байтах с этим:

encodedLength = struct.pack('@I', len(encodedContent)) 

Это не для печати. Вы можете записать его через поток сокетов, который является двоичным потоком, но не через stdout, который является текстовым потоком.

Хитрость использования buffer (как объяснено в How to write binary data in stdout in python 3?) это хорошо, но только для бинарной части (обратите внимание, что вы получите сообщение об ошибке в текстовой части в настоящее время):

sys.stdout.buffer.write(encodedMessage['length']) 

Для текстовой части, просто напишите stdout:

sys.stdout.write(encodedMessage['content']) 

или использовать sys.stdout.buffer шпагатом для преобразования байт:

sys.stdout.buffer.write(bytes(encodedMessage['content'],"utf-8")) 
0

вам необходимо убедиться, что ваш вход - str (unicode) перед записью в stdout/stderr.

в вашем примере:

sys.stdout.write(encodedMessage['length'].decode('utf8')) 
sys.stdout.write(encodedMessage['content']) 

вы можете увидеть, что type(encodedLength)) является bytes в то время как type(encodedContent) является str.

пожалуйста, прочитайте the following answer для получения дополнительной информации о байтах против строки в python3.X

+0

Очень полезно. Благодарю. –

Смежные вопросы