Python 读/写文本文件
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 
原文地址: http://stackoverflow.com/questions/16604826/
Warning: these are provided under cc-by-sa 4.0 license.  You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Read/Write text file
提问by Chris Aung
I am trying to change a some lines in a text file without affecting the other lines. This is what's inside the text file called "text.txt"
我试图在不影响其他行的情况下更改文本文件中的某些行。这是名为“text.txt”的文本文件中的内容
this is  a test1|number1
this is a test2|number2
this is a test3|number2
this is a test4|number3
this is a test5|number3
this is a test6|number4
this is a test7|number5
this is a test8|number5
this is a test9|number5
this is a test10|number5
My objective is to change the line 4 and line 5 but keep the rest same.
我的目标是更改第 4 行和第 5 行,但保持其余不变。
mylist1=[]
for lines in open('test','r'):
    a=lines.split('|')
    b=a[1].strip()
    if b== 'number3':
        mylist1.append('{}|{} \n'.format('this is replacement','number7'))
    else:
         mylist1.append('{}|{} \n'.format(a[0],a[1].strip()))
myfile=open('test','w')
myfile.writelines(mylist1)
Even though the code works, I am wondering if there is any better and efficient way to do it? Is it possible to read the file just by line number?
即使代码有效,我想知道是否有更好更有效的方法来做到这一点?是否可以仅通过行号读取文件?
采纳答案by Lev Levitsky
There is not much you can improve. But you have to write all lines to a new file, either changed or unchanged. Minor improvements would be:
没有太多可以改进的。但是您必须将所有行写入一个新文件,无论是已更改还是未更改。小的改进将是:
- using the 
withstatement; - avoiding storing lines in a list;
 - writing 
lineswithout formatting in theelseclause (if applicable). 
- 使用
with声明; - 避免在列表中存储行;
 lines在else子句中不带格式书写(如果适用)。
Applying all of the above:
应用以上所有内容:
import shutil
with open('test') as old, open('newtest', 'w') as new:
    for line in old:
        if line.rsplit('|', 1)[-1].strip() == 'number3':
            new.write('this is replacement|number7\n')
        else:
            new.write(line)
shutil.move('newtest', 'test')
回答by Ignacio Vazquez-Abrams
No. Files are byte-oriented, not line-oriented, and changing the length of a line will not advance the following bytes.
不会。文件是面向字节的,而不是面向行的,改变一行的长度不会推进后面的字节。
回答by jamylak
import fileinput
for lines in fileinput.input('test', inplace=True):
    # inplace=True redirects stdout to a temp file which will
    # be renamed to the original when we reach the end of the file. this
    # is more efficient because it doesn't save the whole file into memeory
    a = lines.split('|')
    b = a[1].strip()
    if b == 'number3':
        print '{}|{} '.format('this is replacement', 'number7')
    else:
        print '{}|{} '.format(a[0], a[1].strip())
回答by oleg
try this solution
试试这个解决方案
with open('test', inplace=True) as text_file:
    for line in text_file:
         if line.rsplit('|', 1)[-1].strip() == 'number3':
             print '{}|{} \n'.format('this is replacement', 'number7')
         else:
             print line
回答by kampu
It's not wholly clear whether your intent is to identify the lines to be replaced by their value, or by their line number.
不完全清楚您的意图是确定要由它们的value或它们的line number替换的行。
If the former is your intent, you can get a list of lines like this:
如果前者是您的意图,您可以获得如下所示的行列表:
with open('test','r') as f:
    oldlines = f.read().splitlines()
If there's a danger of trailing whitespace, you could also:
如果存在尾随空格的危险,您还可以:
Then you can process them like this:
然后你可以像这样处理它们:
newlines = [ line if not line.strip().endswith('|number3') else 'this is replacement|number7' for line in oldlines]
Open the destination file (I'm assuming you want to overwrite the original, here), and write all the lines:
打开目标文件(我假设您想在这里覆盖原始文件),然后写下所有行:
with open('test','w') as f:
    f.write("\n".join(newlines))
This is a general pattern that's useful for any kind of simple line-filtering.
这是一种通用模式,可用于任何类型的简单线路过滤。
If you meant to identify the lines by number, you could just alter the 'newlines' line:
如果您打算按数字标识行,则可以更改“换行符”行:
 newlines = [ line if i not in (3, 4) else 'this is replacement|number7' for i, line in enumerate(oldlines)]

