🗂
Python の with ~ as 構文
珍しく Python のコードを読む機会があったんですが
with open('./test.txt') as f:
print(f.read());
みたいに with ~ as
みたいなコードを見かけて『これってどういう構文なんだろう』と思ったので覚書です。
with ~ as
構文
さらっと書いちゃうんですが
with EXPRESSION as TARGET:
SUITE
は
manager = (EXPRESSION)
enter = type(manager).__enter__
exit = type(manager).__exit__
value = enter(manager)
hit_except = False
try:
TARGET = value
SUITE
except:
hit_except = True
if not exit(manager, *sys.exc_info()):
raise
finally:
if not hit_except:
exit(manager, None, None, None)
と等価になります。
もう少し簡略的に書いてしまうと
manager = EXPRESSION
TARGET = manager.__enter__()
try:
SUITE
finally:
manager.__exit__()
みたいに EXPRESSION
を評価しつつ SUITE
の前後で __enter__()
と __exit__()
を呼び出す構文になります。
参照: Pythonのwith文の正体
元のコードでは __exit__()
のタイミングで f.close()
を呼び出すことが担保されている感じですねー。
要は RAII みたいな手法を構文で実現している感じですかね?
参照: RAII - Wikipedia
これは以下のようにユーザが拡張して利用することもできます。
class Wrap:
def __enter__(self):
print(">>>>>>>>>>>>>>")
def __exit__(self, *args):
print("<<<<<<<<<<<<<<")
with Wrap() as f:
print("Hello, World!!")
j>>>>>>>>>>>>>>
Hello, World!!
<<<<<<<<<<<<<<
Ruby だと構文ではなくてブロックでこういう仕組みをメソッド側で実現していることが多いと思いますが、他言語でこういう構文を見るのは単純に面白い。
Discussion