У меня есть длительный процесс, называемый Updater, который имеет обновления (к системе ETL), представленные на него. У обновлений есть требования к ресурсам, которым управляет добавление диспетчера контекстов к ExitStack Updater. Некоторые обновления будут включать новую конфигурацию, что означает, что выделенные ресурсы должны быть освобождены из стека, и будет добавлена новая конфигурация ресурса. Мне нужно что-то вроде:Как удалить диспетчер контекста из 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)
Edit: Добавлен известным решением
Глядя на исходном коде 'ExitStack' использует' deque' для хранения оберток для контекстов '.__ exit__' метода так что вам нужно будет чтобы иметь возможность идентифицировать обертку исходным менеджером контекста, который, насколько мне известно, невозможен. Возможно, вам придется переосмыслить (по крайней мере частично) функциональность «ExitStack», чтобы иметь возможность удалять контексты раньше времени. –
@ TadhgMcDonald-Jensen спасибо. Я обнаружил то же самое, что проверял объекты ExitStack в Jupyter Notebook. У них есть ключ закрытия, который является атрибутом '__self__', является менеджером контекста. Я добавлю некоторый код в известное решение, но я надеялся на меньшее «взломанное» решение. Я хотел посмотреть, есть ли более чистое решение, прежде чем я отправлюсь в Python Ideas или добавлю его сам (чего я никогда раньше не делал). – arachnivore