【问题标题】:Why does zmq.setsockopt_string complain about default 'ascii' code?为什么 zmq.setsockopt_string 抱怨默认的“ascii”代码?
【发布时间】:2020-11-26 16:57:41
【问题描述】:

我试图弄清楚我的开发环境是否以某种方式搞砸了,因为“它可以在 [我的同事] 计算机上运行”,但不是我的。我没有解决问题的“实质”,而是致力于我发现的第一个有趣的事情。

我有一段代码不明白为什么一个调用会起作用,而另一个调用不起作用:

import sys
import zmq

if __name__ == "__main__":
    print sys.getdefaultencoding()  # Displays 'ascii'

    zContext = zmq.Context()
    zSocket = zContext.socket(zmq.SUB)

    # This works.
    zSocket.setsockopt_string( zmq.SUBSCRIBE, "Hello".decode('ascii'))

    # This fails with error... why?
    # raise TypeError("unicode strings only")
    #
    # Shouldn't the default encoding for "Hello" be ascii?
    # zSocket.setsockopt_string( zmq.SUBSCRIBE, "Hello")

    zSocket.connect( "tcp://localhost:5000")

我假设对于 setsockopt_string 的工作调用,我正在传递一个 ascii 字符数组。在损坏的代码中,我必须发送一些不是 ascii 的东西,而不是 unicode。我怎么知道传递给 setsockopt_string 的是什么?

也许这甚至不是要问的问题。我只是有点困惑。

任何帮助都会很棒。

这是我的环境:

python --version
Python 2.7.3
#1 SMP Debian 3.2.57-3+deb7u2 x86_64 GNU/Linux

谢谢。

【问题讨论】:

  • 'hello' 是一个字节串。解码时,将其转换为 unicode 字符串(u'hello'),即文本。setsockopt_string 会将您的 unicode u'hello' back 编码为字节('hello')并传递进入setsockopt
  • 你好。感谢你的回答。你能发帖,我可以给你打勾吗?另外,我需要澄清一下,decode 是通过 'ascii' 传递的,那么为什么 decode 会将 'hello' 变成 u'hello'? u'hello' 和 'hello' 看起来不是一样的字节吗?我猜不是。另外,您是说在调用失败的情况下,我将转换后的输入传递给 setsockopt_string 吗? (setsockopt_string 的结果是什么?)
  • u'hello' 是文本。 'hello' 是字节。它们看起来相同,因为 ascii 字符的 unicode 代码点是相同的。但是如果你使用 UTF-8 将u'привет' 编码成字节,你会得到'\xd0\xbf\xd1\x80\xd0\xb8\xd0\xb2\xd0\xb5\xd1\x82'

标签: python encoding zeromq pyzmq


【解决方案1】:

遇到由设置为 setsockopt_string 方法的 unicode/str 值引起的问题,快速解决方法是:

zSocket.setsockopt_string(zmq.SUBSCRIBE, b"Hello")

这将传递字节而不是字符串,或者如果你有变量,那么你应该这样写:

zSocket.setsockopt_string(
    zmq.SUBSCRIBE,
    bytes("Hello", encoding="latin-1")
)

这适用于 python 2 和 3

【讨论】:

  • bytes 是 Python 2 中 str 的别名,因此您不能传入编码。 unicode("Hello", encoding="latin-1") 似乎确实有效。
【解决方案2】:

由于订阅是由另一方创建的,它可以是 Unicode。在将它们设为 ascii 选项的同时,您也可以采用接收器来统一订阅名称。

socket.setsockopt_string(zmq.SUBSCRIBE, topicfilter, encoding='utf-8')

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-10-11
    • 1970-01-01
    • 1970-01-01
    • 2015-06-09
    • 2020-08-12
    • 2016-02-27
    • 1970-01-01
    相关资源
    最近更新 更多