概要
with
文を自分でも活用できるようにする。
内容
環境
macOS Catalina
Python 3.7.0
解決策1 準備
class
を定義する。
with1.py
class Obj():
def __init__(self, name):
print('------start')
self.name = name
def __enter__(self):
return f'hello, {self.name}'
def __exit__(self, type, value, traceback):
#Exception handling here
print(f'with or without exception, finished. bye, {self.name}')
print('------end\n')
__init__
, __enter__
, __exit__
を使い、__enter__
でas
で使うものを返す。
解決策1 実行
with1.py
with Obj('yaruo') as message:
print(message)
with Obj('yaruo') as message:
print(message)
raise RuntimeError()
output
------start
hello, yaruo
with or without exception, finished. bye, yaruo
------end
------start
hello, yaruo
with or without exception, finished. bye, yaruo
------end
Traceback (most recent call last):
File "with1.py", line 25, in <module>
raise RuntimeError()
RuntimeError
できた。
解決策2 準備
builtinのcontextlibを使う。
with2.py
import contextlib
@contextlib.contextmanager
def context(name):
print('------start')
try: #Exception handling can be written in except:
yield f'hello, {name}'
finally:
print(f'with or without exception, finished. bye, {name}')
print('------end\n')
yield
でas
で使うものを返す。
解決策2 実行
with2.py
with context('yaruo') as message:
print(message)
with context('yaruo') as message:
print(message)
raise RuntimeError()
output
------start
hello, yaruo
with or without exception, finished. bye, yaruo
------end
------start
hello, yaruo
with or without exception, finished. bye, yaruo
------end
Traceback (most recent call last):
File "with2.py", line 25, in <module>
raise RuntimeError()
RuntimeError
蛇足
-
return
:終了のイメージ -
yield
:一時停止のイメージ
終了処理のほか、一時的に変数を変更したい時にも使える。
import contextlib
class Config:
a = False
@contextlib.contextmanager
def a_True():
backup, Config.a = Config.a, True
try:
yield
finally:
Config.a = backup
with a_True():
print(Config.a) # True
print(Config.a) # False
参考にさせていただいた頁・本
- 『ゼロから作るDeep Learning③ フレームワーク編』斎藤康毅著 O'REILLY
- https://stackoverflow.com/questions/3774328/implementing-use-of-with-object-as-f-in-custom-class-in-python
感想
with
文を活用する方法がわかって良かった。
今後
Pythonicなコード目指して活用していきたい。