0

我正在使用此 python 代码从给定文件 (source_file.txt) 中提取电子邮件地址,并将这些电子邮件地址写入单独的文件中。(我正在使用 python 3.3)

import urllib.request
import re
import fileinput, glob, string, sys, os
from os.path import join
import os

filePath = "source_file.txt"

if not filePath:
    print("Sorry! Source File could not be located!")
else:
    page = open(filePath, "r")
    pageContent = page.read()
    page.close()

style_normal = re.compile("[-a-zA-Z0-9._]+@[-a-zA-Z0-9_]+.[a-zA-Z0-9_.]+")
style_text_one = re.compile('[-a-zA-Z0-9._]+\s+at\s+[-a-zA-Z0-9_]+\s+dot\s+[a-zA-Z0-9_.]+')
style_text_two = re.compile('[-a-zA-Z0-9._]+\(at\)[-a-zA-Z0-9_]+\(dot\)[a-zA-Z0-9_.]+')

style_normal_list = style_normal.findall(str(pageContent))
style_text_one_list = style_text_one.findall(str(pageContent))
style_text_two_list = style_text_two.findall(str(pageContent))

f = open('emails_file.txt', 'a')
f.write('testing')

for item in style_normal_list:
    print("%s" %item)
    f.write("%s" %item)
for item in style_text_one_list:
    text_one = item.replace(' at ','@')
    text_two = text_one.replace(' dot ','.')
    print(text_two)
    f.write(text_two)

for item in style_text_two_list:
    text_one = item.replace('(at)','@')
    text_two = text_one.replace('(dot)','.')
    f.write(text_two)

问题是当我运行这个文件时,文件被创建,但文件中没有写入任何内容。甚至没有文字“测试”。文件已创建,但为空白。

我已经使用打印语句来检查代码的其他部分是否正常工作。根据python doc,语法是正确的。你们中的任何人都可以指出我在这段代码中犯的任何错误吗?

4

1 回答 1

2

当您调用write文件时,数据实际上并没有立即写入磁盘,而是存储在缓冲区中。每隔一段时间,缓冲区就会被刷新。如果你想控制它,你可以显式调用flush,但通常最好不要——当你close文件时,它会自动刷新。

但是你必须要close这个文件才能工作。当文件对象被删除时,它会自行关闭,但您不能依赖文件对象在任何特定时间甚至永远被删除。(您可以了解它在 CPython 2.7、CPython 3.3、IronPython 等中如何工作的详细信息,以及 CPython 3.3 在 Unix 和 Windows 上如何以不同方式处理退出等等,但您仍然不想依赖这些细节。)

因此,如果您f.close()在代码末尾添加一个显式,那几乎可以解决问题……但不能完全解决。如果其他行引发异常怎么办?然后它永远不会close()接听电话。

try你可以用/解决这个问题finally,但有一个更好的方法,with语句:

with open('emails_file.txt', 'a') as f:    
    f.write('testing')
    # ...
    for item in style_text_two_list:
        text_one = item.replace('(at)','@')
        text_two = text_one.replace('(dot)','.')
        f.write(text_two)

这保证了一旦你到达缩进with块的末尾——即使发生这种情况是因为异常,或者退出程序(或者return从函数中,如果你在一个函数中,或者break从循环中,如果你在一个循环等),f将被关闭。

这在官方教程的文件对象方法中都有解释,但是看看它是如何解释的,我可以想象很多新程序员不会从所写的内容中得到任何东西。只有当您已经了解它的作用时,该with statement文档才真正有意义,并且对于有关缓冲文件对象的解释也是如此…… PEP 343,它介绍了该with语句要好一些,但它花费了尽可能多的时间来谈论关于该功能为何有用的两个先前相关的 PEP。因此,我想许多开发人员对此一无所知是可以理解的。

于 2013-02-05T20:23:36.437 回答