I'm looking at how to do file input and output in Python. I've written the following code to read a list of names (one per line) from a file into another file while checking a name against the names in the file and appending text to the occurrences in the file. The code works. Could it be done better?

I'd wanted to use the with open(... statement for both input and output files but can't see how they could be in the same block meaning I'd need to store the names in a temporary location.

def filter(txt, oldfile, newfile):
    '''\
    Read a list of names from a file line by line into an output file.
    If a line begins with a particular name, insert a string of text
    after the name before appending the line to the output file.
    '''

    outfile = open(newfile, 'w')
    with open(oldfile, 'r', encoding='utf-8') as infile:
        for line in infile:
            if line.startswith(txt):
                line = line[0:len(txt)] + ' - Truly a great person!\n'
            outfile.write(line)

    outfile.close()
    return # Do I gain anything by including this?

# input the name you want to check against
text = input('Please enter the name of a great person: ')    
letsgo = filter(text,'Spanish', 'Spanish2')

推荐答案

Python allows putting multiple open() statements in a single with. You comma-separate them. Your code would then be:

def filter(txt, oldfile, newfile):
    '''\
    Read a list of names from a file line by line into an output file.
    If a line begins with a particular name, insert a string of text
    after the name before appending the line to the output file.
    '''

    with open(newfile, 'w') as outfile, open(oldfile, 'r', encoding='utf-8') as infile:
        for line in infile:
            if line.startswith(txt):
                line = line[0:len(txt)] + ' - Truly a great person!\n'
            outfile.write(line)

# input the name you want to check against
text = input('Please enter the name of a great person: ')    
letsgo = filter(text,'Spanish', 'Spanish2')

And no, you don't gain anything by putting an explicit return at the end of your function. You can use return to exit early, but you had it at the end, and the function will exit without it. (Of course with functions that return a value, you use the return to specify the value to return.)

Using multiple open() items with with was not supported in Python 2.5 when the with statement was introduced, or in Python 2.6, but it is supported in Python 2.7 and Python 3.1 or newer.

http://docs.python.org/reference/compound_stmts.html#the-with-statement http://docs.python.org/release/3.1/reference/compound_stmts.html#the-with-statement

If you are writing code that must run in Python 2.5, 2.6 or 3.0, nest the with statements as the other answers suggested or use contextlib.nested.

Python相关问答推荐

如何将数据帧中的timedelta转换为datetime

删除特定列后的所有列

仅取消堆叠最后三列

为什么在不先将包作为模块导入的情况下相对导入不起作用

为什么在生成时间序列时,元组索引会超出范围?

删除另一个div中的特定div容器

如何将django url参数传递给模板&S url方法?

GEKKO中若干参数的线性插值动态优化

如何将ManyToManyfield用于Self类

具有数值数组问题的递归矩阵构造(广播?)

在Python中用两个图像制作一个图像

改进积分方程式、Worker关键字非函数拟合的scipy.Integrate.quad_vec性能

生成错误结果的DataFrame.groupby.ank?

返回最后一行以上的所有行,直到满足Python中的条件

FASK集合变量未更新(HTML)中的值

如何根据两个日期之间的周数复制行?

我很难用Python Pandas打开旧格式的XLS文件

将函数拟合到曲线上,然后删除某些点

将MultiIndex列的级别转换为具有值的列(取消堆叠列)

Lambda调用未处理,3秒后超时?