[PR]テレビ番組表
今夜の番組チェック


Python超簡易イントロダクション その3

 Python超簡易イントロダクションもいよいよ最終回。 最終回といえば殉職シーンがつきものですが、 このページではそこまでの演出はなかったり。 今度は便利なユーティリティづくりに欠かせない、 ファイル処理や文字列処理などをやってみましょう。

#! /usr/local/bin/python
#
# ザ・特訓3.py (2000/09/24 - 2000/11/02)
#
import sys, os, time, popen2, string, re
from stat import *

# ファイルをオープンし、1行ずつ読みながらテキストの照合をしてみます。
opened = 0
try:
    # ファイルのオープンは組み込み関数openを使います。すると
    # ファイルオブジェクトを返してくるので、そのreadline()や
    # writeline()、close()などを使って処理をします。
    wordsfile = "/usr/dict/words"
    fp = open(wordsfile, "r")
    opened = 1
except IOError, e:
    print "おおっと! " + str(e)
if opened:
    # PythonでもPerlやTclと同様、正規表現を使ったパターンマッチング
    # ができます。これはreというモジュールを使います。
    # 正規表現を何度も繰り返し使う場合は、先にre.compileを使って
    # 「コンパイル」しておきます。
    rep = re.compile("h.*at")

    # readline()は1行ずつ読む関数ですが、ファイル全体を一気に読む
    # read()やreadlines()も便利です。
    # readline()の返す文字列の最後には改行文字が含まれます。
    # ファイルの終りに達したら、長さ零の文字列を返すようになります。
    buf = fp.readline()
    while buf != "":
        # コンパイルした正規表現オブジェクトのsearch()を使うと
        # 適合した情報を含むMatchObjectインスタンスが返ります。
        # 適合しない場合はNoneが返ります。
        m = rep.search(buf)
        if m != None:
            # MatchObjectインスタンスのstart() end()を使うと
            # 何文字目から何文字目までが適合したかが分かります。
            spos = m.start(); epos = m.end();
            print "[%d][%d] %s" % (spos, epos, buf),
        buf = fp.readline()
    fp.close()

# ・Pythonインタープリタの実行時に指定されたコマンドライン引数は、
#   リストsys.argvで受け取ることができます。sys.argv[0]はスクリプトの
#   名前なので、実質的な引数は[1]からです。
# ・プログラムを途中で終了するには、sys.exitを使います。引数はエラー
#   コードで、通常エラー終了の場合は正の整数を使います。
try:
    dname = sys.argv[1]
except IndexError, e:
    print "おおっと! ディレクトリ名を指定してください。"
    sys.exit(1)

# ある文字列がOSファイルシステム上のファイル名やディレクトリ名に
# 該当するかどうかは os.path.isfile(通常ファイル)
# os.path.isdir(ディレクトリ) などで判断できます。
if not os.path.isdir(dname):
    print "おおっと!", dname, "はディレクトリではありませぬ。"
    sys.exit(2)

# ディレクトリに含まれるファイル名のリストを得るには、
# os.listdirを使います。この返すリストには . や .. は含まれません。
try:
    files = os.listdir(dname)
except OSError, e:
    print "ファイル一覧が作れません:", e
    sys.exit(3)
print files

# (下のはコメントです。こんなふうにも書けるということで)
"""
 (ひとやすみ) Pythonには、JavaやOracle PL/SQLを知っている方ならおなじみの
 「例外」(Exception)という機構があります。これは、なんかまずいことが
 起きたら、とりあえず「エラーっぽい」という報告を「例外」として関数の
 呼び出し元に報告するものです。呼び出し元の関数は、下からの報告を受けて
 「自分で処理する」か、
 「さらに自分の呼び出し元に報告を上げる」かを選べます
 (中間管理職と思えばよいでしょう) 報告を自分で責任をもって処理する場合には、

 try:
     例外の報告が出るかもしれない処理
 except 例外の種類, 報告メッセージ:
     エラーの処理(責任をもって)

 こんなようなでtry文とexcept文を使います。
 さらに上司に報告を上げるには、単に何もせずにいればOKです。その結果、
 Python処理系の一番上まで報告が上がってしまうと、ついに社長のお目玉よろしく
 Pythonが勝手にエラーを表示して怒って終了してしまいます。

"""

# 「ls -l」 のように情報を表示してみましょう。
for e in files:
    # os.path.joinは、任意の数の引数で与えられた文字列をディレクトリ
    # 区切り文字(/)で連結したパスを返します。
    fullpath = os.path.join(dname, e)

    # os.statは、statシステムコールが返す情報からなるたっぷるを返す関数です。
    # statモジュールには、下のST_MTIMEやST_MODEのような記号定数が定義されて
    # います。
    s = os.stat(fullpath)

    # time.localtimeは基準時刻からの秒数を
    # (年、月、日、時、分、秒、曜日(日=0)、通し日、サマータイムフラグ)
    # の9項目からなるたっぷるに変換して返します。
    # Pythonは月は1..12です。CやPerlで0..11に慣れている場合要注意。
    mtimes = time.localtime(s[ST_MTIME])
    timespec = time.strftime("%Y/%m/%d %H:%M:%S", mtimes)

    print "%5d %4d %s %s %7d %s %s" % \
      (s[ST_MODE], s[ST_NLINK], s[ST_UID], s[ST_GID], \
       s[ST_SIZE], timespec, e)

# 今度は同じ各ファイルに対し、「file」コマンドを使ってファイルの種類を
# 調べます。
plat = sys.platform
if string.find(plat, "win") != -1:
    print "Windowsでは使えないので、処理をスキップします。"
else:
    for e in files:
        # ~で終わっていたらEmacs系のエディタのバックアップファイルなので、
        # スキップします。
        if e[-1] == "~": continue

        fullpath = os.path.join(dname, e)
        if os.path.isfile(fullpath):
            # popen2モジュールを使います。commands.getoutputでも
            # 同様の処理は可能です。
            # popen2.popen2は、子プロセスのstdoutと子プロセスのstdin
            # からなるたっぷるを返します。親プロセス(このPythonスクリプト)
            # から読めるのは子プロセスのstdout、書けるのはstdinである点に
            # 注意してください。
            cmdobj = popen2.popen2("file " + fullpath)
            fin = cmdobj[0]
            result = string.rstrip(fin.read())
            #print "result: " + result
	    # 最後の4文字
            if result[-4:] == "text":
                print "\"" + e + "\"はテキストファイルです。"

# end.

いかがでしたか? 当サイトではあまりPython言語だけの紹介はせず、 そそくさとPython/Tkinter、PyGTK、PyQtによるGUIプログラミングの話題に飛んでしまいます。 これらはどれもなかなか面白いので、 Pythonの楽しさを何倍にも増幅してくれることでしょう。

セクションのサブメニューに戻る
(first uploaded 2000/11/02 last updated 2002/05/29)