standard online python coding-style

online - Abrir archivo, leerlo, procesarlo y volver a escribirlo-el método más corto en Python



python package naming conventions (6)

Quiero hacer algunos filtros básicos en un archivo. Léelo, hazlo, escríbelo.

No estoy buscando "jugar al golf", pero quiero el método más simple y elegante para lograrlo. Se me ocurrio:

from __future__ import with_statement filename = "..." # or sys.argv... with open(filename) as f: new_txt = # ...some translation of f.read() open(filename, ''w'').write(new_txt)

La instrucción with hace que las cosas sean más cortas ya que no tengo que abrir y cerrar explícitamente el archivo.

¿Alguna otra idea?


Esto parece funcionar:

with open(filename, "r+") as f: new_txt = process(f.read()) f.truncate(0) f.write(new_txt)


Si está buscando el equivalente de python "perl -pi", aquí hay uno bastante bueno:

import fileinput for line in fileinput.input(): # process line

Consulte http://www.python.org/doc/2.5.2/lib/module-fileinput.html para obtener más información.

Hecho de esta manera, usaría su secuencia de comandos python en una tubería para crear el nuevo archivo:

$ myscript.py infile.txt > outfile.txt


Para hacerlo de una manera que no comerá sus datos si se bloquea en el medio:

from twisted.python.filepath import FilePath p = FilePath(filename) p.setContent(process(p.getContent()))


En realidad, una forma más sencilla de usar la entrada de archivo es usar el parámetro inplace:

import fileinput for line in fileinput.input (filenameToProcess, inplace=1): process (line)

Si usa el parámetro inplace, redireccionará stdout a su archivo, de modo que si imprime, lo volverá a escribir en su archivo.

Este ejemplo agrega números de línea a su archivo:

import fileinput for line in fileinput.input ("b.txt",inplace=1): print "%d: %s" % (fileinput.lineno(),line),


Mi fea (pero corta como se dice en la pregunta) solución con expresiones de generador ;

# Some setup first file(''test.txt'', ''w'').write(''/n''.join(''%05d'' % i for i in range(100))) # This is the filter function def f(i): return i % 3 # This is the main part file(''test2.txt'', ''w'').write(''/n''.join(str(f(int(l))) for l in file(''test.txt'', ''r'').readlines())) # And a wrapper for sanity def filter_file(infile, outfile, filter_function) outfile.write(''/n''.join(filter_function(l) for l in infile.readlines()))


Me gustaría ir por la elegancia de una manera diferente: implemente las operaciones de lectura y filtrado de archivos como generadores, escribirá más líneas de código, pero será un código más flexible, mantenible y de rendimiento.

Vea los Trucos de generadores para programadores de sistemas de David M. Beazley, que es algo realmente importante para cualquier persona que escriba este tipo de código para leer.