2017-01-21 2 views
1

ラムダでコンテキストマネージャを使用するにはどうすればよいですか?ハックは受け入れられました。これがラムダの悪い使い方であるとの意見を遅らせてください。ラムダでコンテキストマネージャを使用する方法は?

私はこれを行うことができます知っている:

def f(): 
    with context(): 
     return "Foo" 

しかし、私はこのような何かをしたいと思います:

lambda: with context(): "Foo" 
+0

'F'は、あなたの' lambda'内の変数ではありません。 –

+0

ありがとう、私の部分の構文ミス。一定。 –

答えて

0

コンテキストマネージャでの作業ラムダを取得するための一つの可能​​な回避策は、コンテキストマネージャContextDecoratorを作ることであるラムダではなく、Decoratorパターンを使用することができますので、その後、with文とlambda表現の両方が動作します。

Example

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'))() 
4

あなたがいない、表現していwith作業を置き換えることはできません。式の中で例外やファイナライズを処理する方法がないため、そこにあなたを連れて行くためのハックはありません。

の1つの式はラムダでしか使用できないためです。 withステートメントであり、式ではありません。それを例外処理(try..except..finally)に置き換えて、__enter__ and __exit__ methods__exit__メソッド最初にを格納する)への呼び出しを行う必要があります。ただし、例外処理では現在の式が直ちに終了するため、例外処理はのみで実行できます。 Python Try Catch Block inside lambdaを参照してください。

オプションのみは、代わりに適切な機能を使用することです。

+0

ContextDecoratorはどうですか? –

+0

[こちら](https://gist.github.com/carlthome/31ba4093a6f7029053de02d70fc48ef1)のように。例外が発生した場合に問題がありますか? –

+0

ああ、私はそのことを忘れていました。 'ContextDecorator'はラムダ式の一部ではありません。 'with'ステートメントを含む新しい関数オブジェクトを生成し、元の関数を呼び出し、すべての例外処理を行います。それは違うものです。コンテキストマネージャは、明示的にその使用をサポートする必要があります。 –

関連する問題