2016-09-18 2 views
2

컨텍스트 개체를 선택적으로 만들 수있는 래퍼를 만들려고합니다. 조건이 참이면 랩핑 된 컨텍스트 오브젝트처럼 작동해야하며, 그렇지 않은 경우 조건이없는 컨텍스트 오브젝트처럼 작동해야합니다. 이 예제는 랩핑 된 오브젝트를 한 x 사용하는 데 작동하지만 재사용하지 못합니다.사용자 정의 @ contextlib.contextmanager를 다시 사용하는 방법은 무엇입니까?

예 :

import contextlib 
from threading import Lock 

@contextlib.contextmanager 
def conditional_context(context, condition): 
    if condition and context: 
     with context: 
      yield 
    else: 
     yield 

use_locking = False 
lock = conditional_context(Lock(), use_locking) 
with lock: 
    print('Foo') 
with lock: 
    print('Bar') 

출력 : 당신은 그 contextlib.contextmanager 함께 할 수 없습니다

Foo 
Traceback (most recent call last): 
    File "example.py", line 16, in <module> 
    with lock: 
    File "/usr/lib/python3.5/contextlib.py", line 61, in __enter__ 
    raise RuntimeError("generator didn't yield") from None 
RuntimeError: generator didn't yield 

답변

4

. the docs에서 설명한 것처럼 contextmanager로 만든 컨텍스트 관리자는 원 샷입니다.

당신은 당신이 동일한 개체가 with 문 다수의 재사용 가능하려면 __enter____exit__ 방법과 자신의 클래스를 작성해야합니다 :

from threading import Lock 


class ConditionalContext: 

    def __init__(self, context, condition): 
     self._context = context 
     self._condition = condition 

    def __enter__(self, *args, **kwargs): 
     if self._condition: 
      self._context.__enter__(*args, **kwargs) 

    def __exit__(self, *args, **kwargs): 
     if self._condition: 
      self._context.__exit__(*args, **kwargs) 


use_locking = False 
lock = ConditionalContext(Lock(), use_locking) 
with lock: 
    print('Foo') 
with lock: 
    print('Bar') 
관련 문제