ラムダでコンテキストマネージャを使用するにはどうすればよいですか?ハックは受け入れられました。これがラムダの悪い使い方であるとの意見を遅らせてください。ラムダでコンテキストマネージャを使用する方法は?
私はこれを行うことができます知っている:
def f():
with context():
return "Foo"
しかし、私はこのような何かをしたいと思います:
lambda: with context(): "Foo"
ラムダでコンテキストマネージャを使用するにはどうすればよいですか?ハックは受け入れられました。これがラムダの悪い使い方であるとの意見を遅らせてください。ラムダでコンテキストマネージャを使用する方法は?
私はこれを行うことができます知っている:
def f():
with context():
return "Foo"
しかし、私はこのような何かをしたいと思います:
lambda: with context(): "Foo"
コンテキストマネージャでの作業ラムダを取得するための一つの可能な回避策は、コンテキストマネージャContextDecorator
を作ることであるラムダではなく、Decoratorパターンを使用することができますので、その後、with
文とlambda
表現の両方が動作します。
from contextlib import ContextDecorator
def f(x):
"""Just prints the input, but this could be any arbitrary function."""
print(x)
class mycontext(ContextDecorator):
def __enter__(self):
f('Starting')
return self
def __exit__(self, *exc):
f('Finishing')
return False
with mycontext():
f('The bit in the middle')
mycontext()(lambda: f('The bit in the middle'))()
あなたがいない、表現していwith
作業を置き換えることはできません。式の中で例外やファイナライズを処理する方法がないため、そこにあなたを連れて行くためのハックはありません。
の1つの式はラムダでしか使用できないためです。 with
はステートメントであり、式ではありません。それを例外処理(try..except..finally
)に置き換えて、__enter__
and __exit__
methods(__exit__
メソッド最初にを格納する)への呼び出しを行う必要があります。ただし、例外処理では現在の式が直ちに終了するため、例外処理はのみで実行できます。 Python Try Catch Block inside lambdaを参照してください。
オプションのみは、代わりに適切な機能を使用することです。
ContextDecoratorはどうですか? –
[こちら](https://gist.github.com/carlthome/31ba4093a6f7029053de02d70fc48ef1)のように。例外が発生した場合に問題がありますか? –
ああ、私はそのことを忘れていました。 'ContextDecorator'はラムダ式の一部ではありません。 'with'ステートメントを含む新しい関数オブジェクトを生成し、元の関数を呼び出し、すべての例外処理を行います。それは違うものです。コンテキストマネージャは、明示的にその使用をサポートする必要があります。 –
'F'は、あなたの' lambda'内の変数ではありません。 –
ありがとう、私の部分の構文ミス。一定。 –