4章P75のファイルをopenしてread、readした内容をwriteしてファイルをコピーするというプログラム。
pythonで書くと下記。
#/usr/bin/env #-*- encoding: utf-8 -*- import sys def usage_error(filename): print("{0} old-file new-file".format(filename)) def error_exit(str): print("error: " + str) exit() def unix_like(): import os import stat BUF_SIZE = 1024 argc = len(sys.argv) if argc != 3 or sys.argv[1] == "--help": usage_error(sys.argv[0]) input_fd = os.open(sys.argv[1], os.O_RDONLY) if input_fd == -1: os.close(input_fd) open_flags = os.O_CREAT | os.O_WRONLY | os.O_TRUNC; file_perms = stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IWGRP | stat.S_IROTH | stat.S_IWOTH; output_fd = os.open(sys.argv[2], open_flags, file_perms) if output_fd == -1: os.close(output_fd) while True: buffer = os.read(input_fd, BUF_SIZE) if not buffer: break os.write(output_fd, buffer) if os.close(input_fd) == -1: error_exit("close input") if os.close(output_fd) == -1: error_exit("close output") def pythonic(): argc = len(sys.argv) if argc != 3 or sys.argv[1] == "--help": usage_error(sys.argv[0]) # Open input and output files try: file = open(sys.argv[1], encoding='utf-8') except IOError as e: print("opening file {0}".format(e.strerror)) exit() else: try: lines = file.readlines() finally: file.close() try: out_file = open(sys.argv[2], "w") except IOError as e: print("opening file {0}".format(e.strerror)) quit() else: [out_file.write(line) for line in lines] finally: out_file.close() # [Using python “with” statement with try-except block](http://bit.ly/1cQ3hcK) # ./p75_copy.py p75_copy.py p75_copy_w.txt if __name__ == '__main__': pythonic() unix_like()
Cだとexit()を読んでるけど、pythonだとquitとexitがあって、どうやら中身の実装は同じ模様。
あと、Cだと当然、ファイルが開けたかどうかをファイルディスクリプタを見て判定するけど、pythonでも同じようにファイルが開けたかどうかを判定するには、1回tryでopenをして判定するのがよさそう。
けど、pythonだと下記のwithを使った構文がある。。。
with open(path) as file:
けど、withを使った構文では、ファイルが開けたかどうかをキャッチする方法が用意されてない。 なので、下記のようにtryで囲むのかと思ったが...
try: with open(path) as file:
どうやら、このwithをtryで囲む方法は、newbieがやりがちだが良くないと書かれている。。。
となると、先にpathlibでファイルの有りかを調べてから、withでopenすれば良いのかという案が下記。
def pythonic2(): import pathlib argc = len(sys.argv) if argc != 3 or sys.argv[1] == "--help": usage_error(sys.argv[0]) # Open input and output files input_file = sys.argv[1] output_file = sys.argv[2] if pathlib.Path(input_file).is_file(): with open(input_file, encoding='utf-8') as rfile, open(output_file, 'w', encoding='utf-8') as wfile: try: lines = rfile.readlines() [wfile.write(line) for line in lines] except Exception as e: print("err: {0}".format(e)) # ./p75_copy.py p75_copy.py p75_copy_w.txt if __name__ == '__main__': pythonic2()