3-1. Context manager annotation
13844 ワード
前回のレッスンでは、[exit,enter]magicメソッドをクラス形式で実装し、文を使用してカスタマイズしました。Pythonの内部に少し入ったと言えるでしょう。 このように内部からアクセスする場合,最初はクラス形式で定義してアクセスする方法にすぎない.ただしannotation(@)を使ってアクセスしやすい方法があります。 クラス形式ではなく、関数形式でアクセスします。
Context manager annotation
なぜ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を学ぶ。オープンソースパッケージの導入
発電機と生産量の理解
Reference
この問題について(3-1. Context manager annotation), 我々は、より多くの情報をここで見つけました https://velog.io/@uoayop/3-1.-Context-manager-annotationテキストは自由に共有またはコピーできます。ただし、このドキュメントのURLは参考URLとして残しておいてください。
Collection and Share based on the CC Protocol