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)

問題は、これを実行するとファイルは作成されますが、ファイルには何も書き込まれないことです。「テスト」というテキストすらありません。ファイルは作成されましたが、空白です。

printステートメントを使用して、コードの他の部分が正しく機能しているかどうかを確認しました。Pythonのドキュメントによると、構文は正しいです。このコードで私が犯した間違いを指摘できる人はいますか?

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 343withは少し優れていますが、この機能が役立つ理由についての2つの以前の関連PEP。ですから、多くの開発者がこれを知らないのは理解できると思います。

于 2013-02-05T20:23:36.437 に答える