【问题标题】:Writing a string to a file in python 3.3 failure在 python 3.3 中将字符串写入文件失败
【发布时间】:2013-02-05 19:20:25
【问题描述】:

我正在使用此 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,语法是正确的。 谁能指出我在这段代码中犯的任何错误?

【问题讨论】:

  • 这可能无关紧要,但请尝试在脚本末尾添加f.close()
  • 或者,最好将 f = open('emails_file.txt', 'a') 替换为 with open('emails_file.txt', 'a') as f: 并缩进脚本的其余部分。
  • 我试过@WarrenWeckesser 的方法 f.close() 确实有效。无法想象我因为这种简单的事情而挣扎了这么久:) 谢谢!也得试试 abarnert 谢谢!

标签: python regex python-3.x file-io python-requests


【解决方案1】:

当您对文件调用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 块的末尾时——即使这是由于异常或退出程序(或函数中的returning,如果你在一个函数,或者循环中的breaking,如果你在循环中等等),f 将被关闭。

这在官方教程的Methods of File Object 中都有解释,但是看看它是如何解释的,我可以想象很多新程序员不会从所写的内容中得到任何东西。而with statement 文档只有在您已经了解它的作用时才真正有意义,同样对于有关文件对象被缓冲的解释……PEP 343,它引入了with 语句要好一点,但它花费了同样多是时候讨论前两个相关 PEP 的问题,以及为什么该功能有用。所以,我想很多开发者对此一无所知是可以理解的。

【讨论】:

    猜你喜欢
    • 2014-05-02
    • 1970-01-01
    • 2011-01-30
    • 2015-02-05
    • 1970-01-01
    • 1970-01-01
    • 2011-07-12
    • 2011-10-24
    相关资源
    最近更新 更多