son que los iteradores hace generadores generadoras funciones funcion creacion python file iterator

los - que hace next en python



El iterador del archivo Python sobre un archivo binario con un idioma nuevo (2)

En Python, para un archivo binario, puedo escribir esto:

buf_size=1024*64 # this is an important size... with open(file, "rb") as f: while True: data=f.read(buf_size) if not data: break # deal with the data....

Con un archivo de texto que quiero leer línea por línea, puedo escribir esto:

with open(file, "r") as file: for line in file: # deal with each line....

Que es una abreviatura de:

with open(file, "r") as file: for line in iter(file.readline, ""): # deal with each line....

Esta expresión idiomática está documentada en PEP 234, pero no he podido encontrar un modismo similar para los archivos binarios.

He intentado esto:

>>> with open(''dups.txt'',''rb'') as f: ... for chunk in iter(f.read,''''): ... i+=1 >>> i 1 # 30 MB file, i==1 means read in one go...

Intenté poner iter(f.read(buf_size),'''') pero ese es un error de sintaxis debido a los paréntesis después del invocable en iter ().

Sé que podría escribir una función, pero ¿hay forma de utilizar el idioma for chunk in file: defecto for chunk in file: donde puedo usar un tamaño de buffer frente a una línea?

Gracias por aguantar al novato de Python que intenta escribir su primer guion de Python no trivial e idiomático.


No conozco ninguna forma integrada de hacerlo, pero una función de envoltura es bastante fácil de escribir:

def read_in_chunks(infile, chunk_size=1024*64): while True: chunk = infile.read(chunk_size) if chunk: yield chunk else: # The chunk was empty, which means we''re at the end # of the file return

Luego, en el aviso interactivo:

>>> from chunks import read_in_chunks >>> infile = open(''quicklisp.lisp'') >>> for chunk in read_in_chunks(infile): ... print chunk ... <contents of quicklisp.lisp in chunks>

Por supuesto, puede adaptar esto fácilmente para usar a con bloque:

with open(''quicklisp.lisp'') as infile: for chunk in read_in_chunks(infile): print chunk

Y puedes eliminar la declaración if como esta.

def read_in_chunks(infile, chunk_size=1024*64): chunk = infile.read(chunk_size) while chunk: yield chunk chunk = infile.read(chunk_size)


Tratar:

>>> with open(''dups.txt'',''rb'') as f: ... for chunk in iter((lambda:f.read(how_many_bytes_you_want_each_time)),''''): ... i+=1

iter necesita una función con cero argumentos.

  • un f.read simple f.read todo el archivo, ya que falta el parámetro de size ;
  • f.read(1024) significa llamar a una función y pasar su valor de retorno (datos cargados desde el archivo) a iter , por lo que iter no obtiene una función en absoluto;
  • (lambda:f.read(1234)) es una función que toma cero argumentos (nada entre lambda y f.read(1234) y llama a f.read(1234) .

Hay equivalencia entre los siguientes:

somefunction = (lambda:f.read(how_many_bytes_you_want_each_time))

y

def somefunction(): return f.read(how_many_bytes_you_want_each_time)

y tener uno de estos antes de su código podría simplemente escribir: iter(somefunction, '''') .

Técnicamente puedes saltear los paréntesis alrededor de lambda, la gramática de python lo aceptará.