Extracción de líneas de un bytearray -- python campo con performance campo con python-3.x campo con io camp codereview Relacionados El problema

Extracting lines from a bytearray


1
vote

problema

Español

Esta clase es parte de una utilidad que lee líneas de un conjunto de descriptores de archivos que no se bloquean, bloqueando solo cuando no hay líneas completas para emitir.

  a34  

Esta pregunta es específicamente sobre a35 , que es complicada, confusa y podría no ser tan eficiente como podría ser. Por favor, sugerir formas de hacerlo menos complicado y / o confuso, y más eficiente.

(Sé que podría ser mucho más sencillo si no necesitaba reolvender el manejo universal de una nueva línea, pero desafortunadamente es un requisito del contexto más amplio).

(Si hay algo en la biblioteca estándar que hace algunas o todas las tareas más grandes, que también sería una respuesta bienvenida).

Original en ingles

This class is part of a utility that reads lines from a set of nonblocking file descriptors, blocking only when there are no complete lines to emit.

class NonblockingLineBuffer:     def __init__(self, fd, encoding):         self.fd  = fd         self.enc = encoding         self.buf = bytearray()      def absorb(self):         while True:             try:                 block = os.read(self.fd, 8192)             except BlockingIOError:                 return              if block:                 self.buf.extend(block)             else:                 self.is_open = False                 # We don't close the file here because caller                 # needs to remove the fd from the poll set first.                 return      def emit(self):         def emit1(chunk):             self.emitted_this_cycle = True             return (self.fd, chunk.decode(self.enc).rstrip())          buf = self.buf         self.emitted_this_cycle = False         while buf:             r = buf.find(b'\r')             n = buf.find(b'\n')             if r == -1 and n == -1:                 if not self.is_open:                     yield emit1(buf)                     buf.clear()              elif r == -1 or r > n:                 yield emit1(buf[:n])                 buf = buf[(n+1):]              elif n == -1 or n > r:                 yield emit1(buf[:r])                 if n == r+1:                     buf = buf[(r+2):]                 else:                     buf = buf[(r+1):]          self.buf = buf         if not self.is_open:             self.emitted_this_cycle = True             yield (self.fd, None) 

This question is specifically about emit, which is complicated, confusing, and might not be as efficient as it could be. Please suggest ways to make it less complicated and/or confusing, and more efficient.

(I know it could be much simpler if it didn't need to reimplement universal newline handling, but that is unfortunately a requirement from the larger context.)

(If there's something in the standard library that does some or all of the larger task, that would also be a welcome answer.)

           
   
   

Lista de respuestas

1
 
vote
vote
La mejor respuesta
 
  • Ha pasado por alto una caja de la esquina: mientras normalmente trata Foo *foo = [Foo foo]; 4 como un solo separador, este no es el caso cuando los dos bytes se dividen entre los bloques.
  • Foo *foo = [Foo foo]; 5 podría manejar Las nuevas líneas universales para ti.

Aquí está lo que acompañé; Todavía no es muy bonito, me temo. Inicializar Foo *foo = [Foo foo]; 6 en constructor.

  Foo *foo = [Foo foo]; 7  
 
  • You have overlooked a corner case: while you normally treat \r\n as a single separator, this not the case when the two bytes are split between blocks.
  • splitlines could handle the universal newlines for you.

Here's what I came up with; still not very pretty I'm afraid. Initialize self.carry_cr = False in constructor.

def emit(self):     buf = self.buf     if buf:         # skip \n if previous buffer ended with \r         if self.carry_cr and buf.startswith(b'\n'):             del buf[0]         self.carry_cr = False      lines = buf.splitlines()     if buf:         if self.is_open and not buf.endswith((b'\r', b'\n')):             buf = lines.pop()         else:             if buf.endswith(b'\r'):                 self.carry_cr = True             del buf[:]     self.buf = buf      self.emitted_this_cycle = False     if lines:         self.emitted_this_cycle = True         for line in lines:             yield (self.fd, line.decode(self.enc).rstrip())     if not self.is_open:         self.emitted_this_cycle = True         yield (self.fd, None) 
 
 
 
 

Relacionados problema

8  Contando novedades en un archivo  ( Counting newlines in a file ) 
He comenzado a pasar por tutoriales de nodos en nodoschool.io , y la segunda asignación fue escribir un programa que contará El número de nuevas líneas en un...

2  Implementación de SCPI para el control de instrumentos de prueba  ( Implementation of scpi for control of test instruments ) 
trabajo con equipos de prueba electrónicos. Me gusta poder automatizar las pruebas utilizando sus interfaces de control remoto. He construido un patrón, algun...

11  Escáner en Scala  ( Scanner in scala ) 
que quería implementar 'código> 99887766555443333 / Código> en Scala. El objetivo de esta clase es: implementar una interfaz de colección SCALA (probable...

2  Saltando espacios en blanco al leer el archivo  ( Skipping whitespaces when reading file ) 
En la lectura de un archivo, encontré líneas en blanco (incluso en la parte inferior) se bloquean el programa. Para solucionar esto, he agregado el siguiente ...

1  Buscando y reemplazando el texto  ( Searching and replacing text ) 
Modificador de listas de reproducción simple Este programa es un programa de búsqueda y reemplazo para archivos basados ​​en texto. El objetivo principal ...

5  Convertir una mezcla de Latín 1 y UTF-8 a UTF-8 adecuado  ( Convert a mix of latin 1 and utf 8 to proper utf 8 ) 
El siguiente programa toma una secuencia byte arbitraria como entrada y salidas UTF-8 bien formadas. Todas las secuencias UTF-8 de la entrada se copian sin mo...

2  Lectura de datos de Red Stream  ( Reading data from network stream ) 
Tengo una función para solicitar una actualización del servidor. Proporciono la consulta y también indica la longitud esperada de la respuesta. public ...

6  Bloqueo y comunicación UDP de ASYNC con una cámara IR  ( Blocking and async udp communication with an ir camera ) 
Estoy escribiendo una aplicación Java para controlar una cámara de investigación IR personalizada que se instalará en un avión. La cámara se conecta a la comp...

3  Leyendo un archivo XML grande y analizando los elementos necesarios en MySQLDB  ( Reading a large xml file and parsing necessary elements into mysqldb ) 
Tengo concepto justo en una programación (aprendiz), pero no un código experto para refactorarse al más alto nivel. Estoy tratando de leer un archivo XML enor...

7  Programa de Dados-Rolling  ( Dice rolling program ) 
Soy algo nuevo en la programación. Me gustaría comprender las áreas de código que son basura y podrían estar mejor escritas para mantener el comportamiento ex...




© 2022 respuesta.top Reservados todos los derechos. Centro de preguntas y respuestas reservados todos los derechos