【问题标题】:Encoding: TypeError: write() argument must be str, not bytes编码:TypeError:write() 参数必须是 str,而不是字节
【发布时间】:2017-06-07 07:36:34
【问题描述】:

我对 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 El Capitan 10.11.6、x86 64bit cpu 上运行 python 3.5.1; 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'    

【问题讨论】:

  • 您是否尝试将其转换为如下字符串?sys.stdout.buffer.write(str(encodedMessage['length']))

标签: python json


【解决方案1】:

该示例可能与 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"))

【讨论】:

    【解决方案2】:

    在写入 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中字节与字符串的更多信息

    【讨论】:

    • 非常有帮助。谢谢。
    猜你喜欢
    • 2020-03-29
    • 1970-01-01
    • 2019-11-10
    • 2023-03-19
    • 2018-09-13
    • 2016-11-26
    • 2020-12-03
    • 1970-01-01
    • 2021-11-03
    相关资源
    最近更新 更多