Updater라는 장기 실행 프로세스가 있으며이 프로세스에는 업데이트 (ETL 시스템에 대한 업데이트)가 제출되었습니다. 업데이트에는 컨텍스트 관리자를 Updater의 ExitStack에 추가하여 관리되는 리소스 요구 사항이 있습니다. 일부 업데이트에는 새로운 구성이 포함됩니다. 즉, 영향을받는 리소스가 스택에서 릴리스되어야하며 새로 구성된 버전의 리소스가 추가되어야합니다. 다음과 같은 것이 필요합니다.ExitStack에서 컨텍스트 관리자를 제거하는 방법
with ExitStack() as stack:
ctx_manager = open("file.txt")
f = stack.enter_context(ctx_manager)
...
ctx_pop(ctx_manager, stack) # remove the given context manager from the stack
다음은 내가 작업 한 예이지만 보호 된 멤버에 액세스하는 방법에 의존합니다.
def ctx_pop(cm, stack):
for item in stack._exit_callbacks:
if item.__self__ is cm:
break
else:
raise KeyError(repr(cm))
stack._exit_callbacks.remove(item)
item(None, None, None)
편집 : 추가 알려진 솔루션
소스 코드를 보면'ExitStack'는 당신이 필요로하는 것, 그래서 컨텍스트'.__ exit__' 방법에 대해 래퍼를 저장하는'deque'를 사용 내가 아는 한 가능하지 않은 원래 컨텍스트 관리자에 의해 래퍼를 식별 할 수 있어야합니다. 미리 컨텍스트를 제거 할 수 있으려면 (적어도 부분적으로) 'ExitStack' 기능을 재 작성해야 할 수도 있습니다. –
@ TadhgMcDonald-Jensen 감사합니다. Jupyter Notebook에서'ExitStack' 객체를 검사하는 것과 똑같은 것을 발견했습니다. 그들은 closure의 deque를 가지고 있는데, 이는 '__self__' 속성이 컨텍스트 관리자입니다. 알려진 해결책으로 일부 코드를 추가하겠습니다 만, 해킹 (hack) 솔루션을 줄이기를 희망했습니다. 이전에 Python Ideas에 제출하거나 직접 추가하기 전에 더 깨끗한 솔루션이 있는지 알고 싶었습니다. – arachnivore