Pythonのwithとcontext

2307 ワード

本明細書のすべてのコードはPython 2.7で実行されます.
ほとんどの初心者は、ファイルへの読み取り/書き込み操作を行うときに、操作が終わった後にファイルを閉じるのを忘れ、結果を書かなかったというエラーを犯したことがあると信じています.次のコードに似ています.
>>> f = open('demo.txt', 'w')
>>> f.write('test')

正しい書き方は次のようになります.
>>> f = open('demo.txt', 'w')
>>> f.write('test')
>>> f.close()

ファイルの操作が完了したら、すぐにファイルを閉じる必要があります.このようにするのは1つはファイルのデータが完全であるためで、2つはシステム資源を節約して、3つは引き起こす可能性のあるデッドロックを防止します.
第2の書き方は私たちの要求を満たすことができるようです:書類の書くことを完成した後で、すぐに書類を閉じました.しかし、問題は依然として発生しています.ファイルを閉じる操作は、書き込み中にディスクがいっぱいになったなどのプログラム異常のために実行されません.では、書類が必ず閉鎖されることを保証する方法はありますか?try...finallyを使用して、異常が発生した場合のファイルのクローズを処理することを提案する人もいるかもしれません.この方法は可能だが、優雅ではない.本当に公式に推奨されている方法は、with文を使用して操作することです.
>>> with open('demo.txt', 'w') as f:
>>>     f.write('text')

これでずっと簡潔になったのではないでしょうか.
次に、with...as...文の実行手順を見てみましょう.
  • 式の値を計算し、コンテキスト管理オブジェクトを返し、ハンドルに割り当てます.
  • は、呼び出しのためにコンテキストマネージャの__enter__および__exit__メソッドをそれぞれロードする.
  • コンテキストマネージャを呼び出す__enter__メソッド.
  • は、withの文ブロックを実行する.
  • 前のステップが正常に実行された場合、__exit__が実行される.
  • ステップ4の実行で異常が発生した場合、異常情報は__exit__に伝達され、__exit__の実行結果がfalseであれば異常は上へ放出され続け、そうでなければプログラムを実行し続ける.

  • 以上の実行メカニズムは、正常と異常が発生した場合、ファイルが正しく閉じられることを保証します.コンテキストマネージャの概念も理解しました.__enter____exit__によってプログラムの実行環境を定義し、プログラムのエントリと終了の問題を処理します.
  • __enter__():実行時のコンテキスト環境に入り、withはその戻り値(すなわち、コンテキストオブジェクト)をハンドルにバインドする(上記ではf).
  • __exit__(exc_type, exc_value, traceback):運転を終了する際の処理方法は、異常処理、現場清掃作業に用いることができる.

  • 次に、本明細書の最後にコンテキストマネージャを作成します.
    class dbHelper(object):
        import config
        import time
        def __enter__(self):
            db.connect(config.db_addr)
            print 'db connect at '+str(time.time())
        def __exit__(self, exc_type, exc_value, traceback):
            db.shutdown()
            if not exc_type:
                return False
            else:
                logger.error(exc_type, exc_value, traceback)
                return True