简体   繁体   English

在python 3.3中将字符串写入文件失败

[英]Writing a string to a file in python 3.3 failure

I'm using this python code to extract email addresses from a given file (source_file.txt) and to write those email addresses in a separate file. 我正在使用此python代码从给定文件(source_file.txt)中提取电子邮件地址,并将这些电子邮件地址写入单独的文件中。 (I'm using python 3.3) (我正在使用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)

The problem is that when I run this the file gets created, but nothing gets written in the file. 问题是,当我运行此文件时,文件会被创建,但文件中没有任何内容。 Not even the text 'testing'. 甚至没有文字'测试'。 File is created but it is blank. 文件已创建,但它是空白的。

I have used the print statements to check whether other parts of the code is working correctly. 我已经使用print语句来检查代码的其他部分是否正常工作。 According to the python doc the syntax is correct. 根据python doc ,语法是正确的。 Can any of you point out any mistakes I have made in this code? 你能否指出我在这段代码中犯的任何错误?

When you call write on a file, the data doesn't actually get written to disk immediately, it gets stored in a buffer. 当您对文件调用write时,数据实际上不会立即写入磁盘,而是存储在缓冲区中。 Every so often, the buffer is flushed. 每隔一段时间,缓冲区就会被刷新。 You can explicitly call flush if you want to control it, but it's usually better not to—when you close the file, it automatically flushes. 如果要控制它,可以显式调用flush ,但通常最好不要在close文件时自动刷新。

But you have to close the file for this to work. 但是你必须close文件才能工作。 When a file object gets deleted, it closes itself, but you can't rely on the file object getting deleted at any particular time, or even ever. 当文件对象被删除时,它会自行关闭,但您不能依赖于在任何特定时间甚至永远删除文件对象。 (You can learn the details of how it works in CPython 2.7, CPython 3.3, IronPython, etc., and how CPython 3.3 handles exit differently on Unix vs. Windows, and so on, but you still wouldn't want to rely on those details.) (您可以在CPython 2.7,CPython 3.3,IronPython等中了解它的工作原理,以及CPython 3.3如何处理在Unix与Windows上的不同退出等等,但您仍然不希望依赖这些细节。)

So, if you add an explicit f.close() at the end of your code, that almost solves the problem… but not completely. 因此,如果在代码末尾添加一个显式的f.close() ,那几乎可以解决问题......但不是完全解决。 What if some other line raises an exception? 如果其他一些行引发异常怎么办? Then it will never get to the close() call. 然后它永远不会进入close()调用。

You can solve this with try / finally , but there's a better way, the with statement: 你可以用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)

This guarantees that as soon as you get to the end of the indented with block—even if that happens because of an exception, or quitting the program (or return ing from the function, if you're in a function, or break ing from the loop, if you're in a loop, etc.), f will be closed. 这保证了只要你能缩进结束with块即使出现这种情况,因为异常,或退出程序(或return从功能ING,如果你在一个函数,或break由荷兰国际集团循环,如果你在循环中,等等, f将被关闭。

This is all explained in Methods of File Object in the official tutorial, but looking over how it's explained, I can imagine a lot of new programmers wouldn't get any of that out of what's written. 这在官方教程中的文件对象方法中都有解释,但是看看它是如何解释的,我可以想象很多新程序员不会从编写的内容中得到任何结果。 And the with statement documentation only really makes sense if you already understand what it does, and likewise for the explanations about file objects being buffered… PEP 343 , which introduced the with statement is a little better, but it spends as much time talking about what's wrong with the two previous related PEPs as about why the feature is useful. 如果您已经理解它的作用,那么with statement文档才真正有意义,同样对于缓冲文件对象的解释... PEP 343 ,它引入了with语句稍微好一点,但它花了很多时间讨论什么是以前的两个相关PEP错误地说明了该功能为何有用。 So, I guess it's understandable that many developers don't know any of this. 所以,我想很多开发人员都不知道这一点是可以理解的。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM