2016-03-02 26 views
-1

我想在python中读取它之后立即删除一行。刚读完之后删除一行

with open("pages_Romance") as f: 
    for line in f: 
     print "Page: " + line 
     #Do something with the line 
     delete_a_line("pages_Romance", line) 

我的功能delete_a_line实现,如:

def delete_a_line(path_file, line): 
    with open(path_file, "r") as f: 
     urls = f.readlines() 
     if len(urls) == 1: 
      print "File " + path_file + " deleted" 
      os.remove(path_file) 
     else: 
      with open(path_file, "w") as f: 
      for url in urls: 
       if url != line: 
        f.write(url) 
       else: 
        print url 

我的文件pages_Romance包含200周的网址(一个由线),每次我读的URL的时间我想删除它。问题是每次启动脚本时,我在同一个地方得到同样的问题,我的文件中的URL编号163被切断,然后脚本停止。它工作得很好,如果我得到小于163名的网址,但如果我有163以上的网址,我会得到下面的输出:

Page: http://www.allocine.fr/films/genre-130 

然后脚本停止。我应该有:

Page: http://www.allocine.fr/films/genre-13024/?page=163 

我你们可以帮我弄清楚这个问题。如果你愿意,你可以试试这个脚本,它将与200页的URL创建文件:

def create_url_file(): 
    with open("pages_Romance", "w") as f: 
     for i in range(1,201): 
      f.write("http://www.allocine.fr/films/genre-13024/?page=" + str(i) + "\n") 
+2

从文件中删除行对我来说似乎很奇怪。你总是可以用'urls = [line.rstrip()for line in file]',然后简单地用urls.pop(0)''把它们一个一个拉出来......如果你觉得有必要这样做。 –

+2

要知道为什么它停在163处,我们需要知道'#用线做了些什么“。但通常情况下,您不应该同时打开同一个文件3次,并尝试使用3个不同的文件处理程序对其进行读取和写入。 – Stuart

+0

这是为了抓取一个网站,我希望能够在连接问题的情况下重新启动抓取过程 – mel

回答

3

删除从存储在磁盘上的文件的线是不容易的。大多数解决方案 - 就像您的尝试 - 实际上涉及将整个文件读入内存(一行一行或一次全部),然后再将其全部写回到磁盘,除了要删除的行之外。

所以更自然的方法是在迭代和处理行的同时,将想要保留的行写入新文件。然后您可以删除旧文件并根据需要将其替换为新文件。这避免了将整个文件读入内存。

with open("pages_Romance") as in_file, open("pages_Romance_temp", "w") as out_file: 
    for line in in_file: 
     print "Page: " + line 
     #Do something with the line 
     if delete_this_line == False: 
      out_file.write(line) 

但是,如果你的文件很短,只考虑读这一切到内存中,并用它作为处理线的阵列,它可以简化您的其他代码。

with open("pages_Romance") as f: 
    urls = f.readlines() 

# Do stuff with urls 
urls.remove(unwanted_line) 
# etc. 

with open("pages_Romance", "w") as f: 
    f.writelines(urls) 
2

我怀疑你正在迭代你正在同时改变的文件。你的外部循环打开文件,你的内部循环会改变文件的长度。尝试仅从顶级函数进行迭代。

1

尽管我不知道为什么它在处理163行后出现断点,但可能是因为在原始with块中仍然打开时,您正在更改delete_a_line中的文件。我能够得到它通过打开和调用delete_a_line收盘前在每个外迭代的文件工作,所以该文件从来没有一次在两个地方开通:

f = open("pages_Romance") 
while f: 
    line = f.readline() 
    print "Page: " + line 
    #Do something with the line 
    f.close() 
    delete_a_line("pages_Romance", line) 
    try: 
     f = open("pages_Romance") 
    except IOError: 
     f = None 

此外,delete_a_line无法删除文件本身如果它是空的,因为它仍然是打开的(你试图从with块中删除它)。一个快速的解决办法是设置一个标志,然后删除该文件的外侧块:

def delete_a_line(path_file, line): 
    delete_flag = False 
    with open(path_file, "r") as f: 
     urls = f.readlines() 
     if len(urls) == 1: 
      delete_flag = True 
     else: 
      with open(path_file, "w") as f: 
       for url in urls: 
        if url != line: 
         f.write(url) 
        else: 
         print url 
    if delete_flag: 
     print "File " + path_file + " deleted" 
     os.remove(path_file) 

然而,我与其他人同意,我想尝试不同的方法来你正在试图解决的问题而不是不断删除文件中的单行。我上面概述的解决方案效率很低。

相关问题