2013年3月22日金曜日

python でファイルダンプ(クラス風味)

python のファイルダンプを java のコーディングでためしたクラス風味で書き直してみた。コンストラクタにファイルIOの処理を入れていいのだろうか。java と違って例外処理は書いても書かなくても動作するので、ヒューマンエラーなどで起きそうなエラーは補足して、それ以外は python のtraceback に任せるでいいのかな・・・

この件に関してはこの書籍の「1.7 例外」の中に記載されている以下の文に大いに助けられました。意外と python の例外の処理方針について言及している書籍は少ない気がします。
Javaとは違い、Pythonの関数は、自身がどのような例外を送出するのかを宣言しない。発生しうる例外のうち捕捉すべきものを見定めるのはあなたの責任だ。
#! /usr/bin/python
# -*- coding: utf-8 -*-
import sys

class Dump:
    def __init__(self,fname):
        try:
            self.infile = open(fname, 'r')
        except Exception as e:
            print u"ファイルオープン失敗"
            raise e

        self.data = self.infile.read()
        self.infile.close()
        self.offset = 0

    def adrdump(self):
        print "%08x" % self.offset,

    def hexdump(self,p):
        output = [];
        for i in range(len(p)):
            output.append(" %02x" % ord(p[i]))
            if i == 7:
                output.append(" -")
        print ":%-50s" % ''.join(output),

    def chrdump(self,p):
        output = [];
        for i in range(len(p)):
            if ( (0x00<=ord(p[i]) and ord(p[i])<=0x1f) or 0x7f<=ord(p[i])) :
                output.append(".")
            else :
                output.append(p[i])
        print ": %-16s" % ''.join(output),

    def next(self):
        self.now    = self.offset
        self.offset = self.offset + 16
        return(self.data[self.now : self.now+16])

    def isnext(self):
        self.ret = False
        if len(self.data) > self.offset:
            self.ret = True
        return(self.ret)

    def display(self):
        while(disp.isnext()):
            buf = self.next()
            self.adrdump()
            self.hexdump(buf)
            self.chrdump(buf)
            print

if __name__ == "__main__":
    try:
        disp = Dump(sys.argv[1])
        disp.display()
    except Exception as e:
        print u"異常終了:",sys.exc_info()[0]
        print u"type" + str(type(e))
        print u"args" + str(e.args)
        print u"message" + e.message
        print u"e自信" + str(e)