iter(callable, sentinel) form on byte array

Viewed 82

I am using an API that returns messages terminated by a \x04 (end of transmission) byte. I would like to catch this byte in a nice way. This is the code I wrote:

# 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

I would like to make this solution work with arbritrary buffer size. Is there an way to do so without crippling performance, or should I use a generator/classic while True with recv(1024)?

1 Answers

You could code it either of the two following ways:

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

or more succinctly as:

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

Sample usage:

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

Basically these turn the local read() function into a very specialized decorator (function that returns a function).

Related