2008-10-22 48 views
13

我想对文件进行一些基本的过滤。阅读它,做处理,写回。打开文件,读取它,处理并写回 - 在Python中最短的方法

我不是在寻找“打高尔夫球”,而是想要最简单最优雅的方法来实现这一点。我想出了:

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声明让事情更短,因为我没有明确地打开和关闭文件。

还有其他想法吗?

回答

25

实际使用的FileInput一个简单的方法是使用就地参数:

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

如果您使用inplace参数,它会将stdout重定向到您的文件,这样如果您执行打印,它将回写到您的文件。

这个例子添加行号文件:

import fileinput 

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

这似乎工作:

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

只有在`f.truncate(0)`后面调用`f.seek(0)`时才适用,否则新文件以11个零字节(Linux上的Python 2.7.3)开头。 – scai 2012-09-07 11:14:08

4

我会去的优雅不同的方式:执行你的文件读取和过滤操作为发电机,你会写更多的代码,但它会更灵活,可维护和高性能的代码。

查看David M. Beazley的Generator Tricks for Systems Programmers,这对于任何编写这类代码的人来说都是非常重要的。

+0

优秀的链接 - 谢谢!我有点担心调试管道的难度增加,但这种力量是不可否认的。 – 2008-10-23 04:09:35

+1

测试驱动开发是你的朋友。 – 2008-10-23 09:00:16

2

如果您正在寻找蟒蛇相当于“的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 
+0

虽然这并没有真正帮助我,因为我想回写同一个文件。对于同一个文件,重定向不会以这种方式工作 – 2008-10-23 16:16:53

1

要做到这一点的不会eat your data,如果你在中间崩溃其中一种方式:

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

我的丑(但如问题陈述短)与generator expressions解决方案;

# 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())) 
相关问题