Python Glossary English

Python 3.7+Асинхронное программированиепонятие

asyncio.BufferedProtocol

протоколы и транспорты

Потоковый протокол с ручным буфером: цикл просит буфер через get_buffer(), пишет в него данные и сообщает их длину в buffer_updated(). Появился в Python 3.7.

Синтаксис

class P(asyncio.BufferedProtocol): def get_buffer(self, sizehint): ...; def buffer_updated(self, nbytes): ...

Учащемуся этот уровень обычно не нужен: для TCP есть потоки asyncio.open_connection() и asyncio.start_server(), для процессов — asyncio.create_subprocess_exec(). BufferedProtocol — оптимизация поверх Protocol: данные пишутся прямо в ваш bytearray без создания нового bytes на каждую порцию. Это выигрыш только при очень больших потоках; get_buffer() обязан вернуть непустой изменяемый буфер, а читать надо ровно nbytes из buffer_updated(), а не весь буфер — хвост там остался от прошлых порций.

Примеры

import asyncio
import socket
class Reader(asyncio.BufferedProtocol):
    def __init__(self):
        self.buf = bytearray(16)
        self.chunks = []
    def get_buffer(self, sizehint):
        return self.buf
    def buffer_updated(self, nbytes):
        self.chunks.append(bytes(self.buf[:nbytes]))  # ровно nbytes, не весь буфер
async def main():
    loop = asyncio.get_running_loop()
    left, right = socket.socketpair()
    transport, proto = await loop.create_connection(Reader, sock=left)
    right.sendall(b'hello')
    await asyncio.sleep(0.01)
    print(proto.chunks)  # → [b'hello']
    transport.close()
    right.close()
asyncio.run(main())

См. также

Открыть в полном глоссарииdocs.python.orgСообщить о неточности