编码:TypeError:write()参数必须是str,而不是字节

时间:2017-01-22 19:47:25

标签: python json

我对python有一个基本的把握,但我不清楚处理二进制编码问题。我试图从firefox-webextensions示例运行示例代码,其中python脚本发送由javascript程序读取的文本。我一直遇到编码错误。

python代码是:

#! /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

在OS X上运行python 3.5.1 El Capitan 10.11.6,x86 64位cpu; firefox开发人员编辑52.0

我正在使用的python脚本,如上所示,从原来的最小化 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'    

2 个答案:

答案 0 :(得分:3)

该示例可能与Python 2兼容,但Python 3中的内容已发生变化。

您正在使用以下内容生成长度为 bytes 的二进制表示:

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"))

答案 1 :(得分:1)

在写入stdout / stderr之前,你需要确保你的输入是str(unicode)。

在你的例子中

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

您可以看到type(encodedLength))bytestype(encodedContent)str

请阅读the following answer以获取有关python3.X中字节与字符串的更多信息