rabbitfoot530's diary

読んだ本と、プログラムに関することのメモです。好きな言語は、C++, Python, Golang, TypeScript。数学・物理・学習理論も好きです。

PythonによるLinuxプログラミングインタフェース(3章 perror)

the linux programming interfaceというバイブルに載ってるコードをpythonで書くとどうなるのか、個人的なメモ。

ただ、同じコードをos.xxxとかで書くのは面白くなさそうなので、pythonならどうやるのかを調べながら書いていこうと思う。

というわけで、早速p51のperrorに関するコードから。

fd = open(pathname, flags, mode);

if (fd == -1) {

perror("open");

    exit(EXIT_FAILURE);

}
#/usr/bin/env
# -*- coding: utf-8 -*-

pathname = "./nothing"
#pathname = "p51_perror.py"

# openのエラーを補足。おそらく、この書き方がCのエラー補足の書き方に近いのかな?
try:
    f = open(pathname, encoding='utf-8')
    print("open")
except IOError as err:
    print("err1: ", err)

 
# けど、普通pythonでopenするときって、with 〜 asでopenしてcloseはwithにお願いしちゃうと思う。
# けど、withをtryで囲むやり方はpythonicじゃないって書いてあって、良くないと書かれているものもある。

try:
    with open(pathname, encoding='utf-8') as file:
        print("with stmt open")
except IOError as err:
    print("err2: ", err)

 
# そこででてくるのがcontextlibのcontextmanager。
#これを使うと、my_openのような関数も書けるみたい。openの前後でやりたいことを入れ込める。
# 前処理、後処理とかに使えるのかな。

from contextlib import contextmanager
@contextmanager
def my_open(*args, **kw):
    try:
        fp = open(*args, **kw)
    except Exception as err:
        print("err3: ", err)
    else:
        yield fp
        print("in else stmt")
        fp.close()
    finally:
        print("end")

with my_open(pathname) as fp:
    print("my_open")

#classを作って、__enter__が前処理、__exit__が後処理にしてopenの処理をさせることもできる。

class MyOpen2(object):
    def __enter__(self):
        print("__ENTER__")

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("__EXIT__")

with MyOpen2():
    print("middle")