【问题标题】:iter(callable, sentinel) form on byte array字节数组上的 iter(callable, sentinel) 形式
【发布时间】:2018-11-11 19:09:32
【问题描述】:

我正在使用返回由 \x04(传输结束)字节终止的消息的 API。我想以一种很好的方式捕捉这个字节。这是我写的代码:

# Only works if buffer size is 1 byte
read = lambda: self._sslsocket.recv(1)

response = b''
for data_buffer in iter(read, b'\x04'):
    response += data_buffer

我想让这个解决方案适用于任意缓冲区大小。有没有办法在不影响性能的情况下这样做,或者我应该在 True 和 recv(1024) 的情况下使用生成器/经典?

【问题讨论】:

  • 这可能是因为我不是套接字编程方面的专家,但我不确定我是否理解更大的缓冲区大小有什么问题。您是否担心一次只获取一个字节很慢,而您宁愿获取一堆,然后以某种方式在您自己的代码中将它们分解为一次一个字节的流?还是有一些更大的问题(比如'\x04' 字节在更大的字符串中间丢失)?
  • 对前者是。我的问题是使用 socket.recv(1) 一次获取一个字节,因为这会对每个字节进行一次系统调用。我担心这会比简单地获取更大的缓冲区,然后在我的代码中处理该缓冲区要慢。对于后一个问题,这不是我的问题,而是 API 的问题,如果它发生的话,因为它的规范说它不返回 '\x04' 字节,而不是最后。

标签: python iterator generator callable


【解决方案1】:

您可以通过以下两种方式之一对其进行编码:

def read(bufsize):
    return lambda: self._sslsocket.recv(bufsize)

或者更简洁:

read = lambda bufsize: lambda: self._sslsocket.recv(bufsize)

示例用法:

response = b''
for data_buffer in iter(read(1), b'\x04'):
    response += data_buffer

基本上这些将本地 read() 函数变成了一个非常专业的装饰器(返回函数的函数)。

【讨论】:

  • 我认为 OP 关心的是一次只读取一个字节;您正在定义一个更通用的函数,用于一次读取一个字节。
  • @chepner:我不同意 OP 的担忧是什么,也不同意你声称我的回答是做什么的。定义的 read() 函数可用于一次读取任意数量的字节,方法是向其传递不同的 bufsize 参数。
猜你喜欢
  • 2020-05-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-09-16
  • 1970-01-01
  • 2013-07-24
相关资源
最近更新 更多