Открыть файл, прочитать его, обработать и записать обратно - самый короткий метод в Python - PullRequest
13 голосов
/ 23 октября 2008

Я хочу сделать базовую фильтрацию файла. Прочитайте это, сделайте обработку, напишите это назад.

Я не ищу "игры в гольф", но хочу самый простой и элегантный метод для достижения этой цели. Я придумал:

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)

Оператор with делает вещи короче, поскольку мне не нужно явно открывать и закрывать файл.

Есть еще идеи?

Ответы [ 6 ]

26 голосов
/ 23 октября 2008

На самом деле более простой способ использования fileinput - использовать параметр inplace:

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

Если вы используете параметр inplace, он перенаправит стандартный вывод в ваш файл, так что, если вы сделаете печать, он запишет обратно в ваш файл.

Этот пример добавляет номера строк в ваш файл:

import fileinput

for line in fileinput.input ("b.txt",inplace=1):
    print "%d: %s" % (fileinput.lineno(),line),
4 голосов
/ 23 октября 2008

Я бы пошел на элегантность другим путем: реализуйте свои операции чтения файлов и фильтрации в качестве генераторов, Вы напишите больше строк кода, но это будет более гибкий, обслуживаемый и производительный код.

См. Генераторские хитрости Дэвида М. Бизли для системных программистов , что действительно важно для любого, кто пишет код такого типа для чтения.

3 голосов
/ 23 октября 2008

Это похоже на работу:

with open(filename, "r+") as f:
    new_txt = process(f.read())
    f.truncate(0)
    f.write(new_txt)
2 голосов
/ 23 октября 2008

Если вы ищете python-эквивалент "perl -pi", вот довольно неплохой:

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

Подробнее см. http://www.python.org/doc/2.5.2/lib/module-fileinput.html.

Сделано так, что вы будете использовать ваш скрипт на python для создания нового файла:

$ myscript.py infile.txt > outfile.txt
1 голос
/ 23 октября 2008

Чтобы сделать это так, чтобы не съел ваши данные , если вы потерпели крах в середине:

from twisted.python.filepath import FilePath
p = FilePath(filename)
p.setContent(process(p.getContent()))
0 голосов
/ 05 декабря 2008

Мое уродливое (но короткое, как указано в вопросе) решение с выражениями генератора ;

# 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()))
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...