3-1. Context manager annotation


前回のレッスンでは、[exit,enter]magicメソッドをクラス形式で実装し、文を使用してカスタマイズしました。Pythonの内部に少し入ったと言えるでしょう。 このように内部からアクセスする場合,最初はクラス形式で定義してアクセスする方法にすぎない.ただしannotation(@)を使ってアクセスしやすい方法があります。 クラス形式ではなく、関数形式でアクセスします。

Context manager annotation

  • 今日のキーワード
  • Decorator、Contextlib、ContextManager、
  • と比較

    なぜcontextlibアクセサリーに関数としてアクセスするのですか?🤔


    コードは直感的で、簡単です。 コードの数が減っているので例外処理がしやすく、読みやすさが良い。 関数なので、再利用性がいいです。

    概念は,以前クラス形式で記述されたコードを関数形式に変換することによって理解される.

    装飾:クラスシェイプクラスシェイプ


    🔗 2-4. Context Managerコメントリンク
    import contextlib
    
    class MyFileWrite():
        def __init__(self,file_name, method):
            self.file_obj = open(file_name,method)
    
        def __enter__(self):
            return self.file_obj
        
        def __exit__(self, exc_type, value, trace_back):
            if exc_type:
                print('Logging exception {}'.format(exc_type, value, trace_back))
            self.file_obj.close()
    
    with MyFileWrite('./testfile3.txt','w') as f:
        f.write('context manager test3\ncontextllib test3.')

    装飾:関数の形式

    import contextlib
    
    @contextlib.contextmanager
    def my_file_writer(file_name, method):
        f =  open(file_name,method)
    
        yield f #__enter__
        f.close() # __exit__
        
    with my_file_writer('testfile4.txt','w') as f:
        f.write('Context Manager Test4.\nContextlib Test4')
    特長 クラス形式に比べて、コードはずっと簡単です。 enter文は個別に定義されません。代わりに発電機を使う。

    enter、jner ratorではなくexit?🤔 発電機は小さなモータを生成する関数です。 イテレーションは、クラス内でメソッドを個別に実装する必要があります。 関数ではjenner ratorはyieldというキーワードを使うだけで終わります。 したがってjenner layerは、ウィジェットよりもずっと簡単です。 「最終品目」を宣言すると、enter構文と同じ役割を果たします。 降伏構文はexit構文として定義されます。 発電機と生産量 一度にメモリに格納するのではなく、要素を1つずつ返します。 戻る場所を覚えておいてください。 降伏を使用して、値を関数に渡しながら、コードを関数に譲ります。 上のコードに屈服と書くと、内部では「あ~ここにwith文が入っていたのか」と思われます。

    タイマー機能:クラス別実施


    🔗 2-5. Context Managerコメントリンク
    import time
    
    class ExecuteTimer(object):
        def __init__(self, msg):
            self._msg = msg
        
        def __enter__(self):
            self._start = time.monotonic()
            return self._start
    
        def __exit__(self, exc_type, exc_value, exc_traceback):
            if exc_type:
                print("Logging exception {}".format((exc_type, exc_value, exc_traceback)))
            else:
                print('{}:{} s'.format(self._msg, time.monotonic() - self._start))
            return True
    
    with ExecuteTimer('Start Job') as v:
        print('Received start monotonic : {}'.format(v))
        #excute job
        for i in range(100000000):
            pass
        
        raise Exception('Raise! Exception!!')

    タイマ機能:関数による実装

    import time
    
    @contextlib.contextmanager
    def ExcuteTimerDc(msg):
        start = time.monotonic()
        try:
            yield start #__enter__
        except BaseException as e:
            print('Logging exception: {}:{}'.format(msg,e))
            raise #예외 발생 시 상위 클래스로 던짐
        else: #__exit__
            print('{}: {}s'.format(msg,time.monotonic()-start))
    
    with ExcuteTimerDc('start job') as v:
        print('received start monotonid : {}'.format(v))
        for i in range(10000000):
            pass
        # raise value error : 예외처리
        raise ValueError('occurred.')
    例外処理 fmに従って異常処理を行う場合、class形式がより良い。 どうしたんですか。🤔 エラータイプ、エラー値、トレーサビリティパッケージがあるので、より丁寧に処理できます。

    [ソース]

  • インフラストラクチャ-すべての人向けPython:必要な文法Featを学ぶ。オープンソースパッケージの導入

  • 発電機と生産量の理解