Я ищу некоторые пояснения о том, как обрабатывать исключения на этапе установки менеджера контекста, в случае (например), когда файл, к которому я пытаюсь получить доступ, не существует.
Немного предыстории: я создаю подкласс класса Maps
из другой библиотеки, которая предоставляет доступ к некоторым данным на диске.Maps
создает соответствующее имя файла для доступа на основе некоторой информации, которую я передаю при создании экземпляра.Не совсем просто предсказать имя файла, которое Maps
пытается загрузить.
Maps
не закрывает базовый файловый объект, поэтому я пытаюсь исправить это в моем подклассе, указав __enter__
и__exit__
.
class BetterMaps(Maps):
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.data.close()
Итак, мы можем сделать что-то вроде:
with BetterMaps(name, releaseversion) as bettermaps:
do_work_here(bettermaps)
и объект файла действительно закрыт. Однако , это работает только тогда, когда базовый файл действительно существует: если файл не существует, то AssertionError
или NoMapsHereError
повышается, в зависимости от конкретных обстоятельств.В парадигме, которую я использовал ранее, я создал Maps
что-то вроде:
try:
maps = Maps(name, releaseversion)
except (AssertionError, NoMapsHereError) as e:
proceed = False
else:
proceed = True
if proceed:
do_work_here(maps)
, который обрабатывал исключения в случае отсутствия данных для чтения.
Теперь яЯ не уверен, как встроить это поведение в синтаксис менеджера контекста, который я использую.До сих пор я пытался изменить __enter__
для регистрации существования данных и вернуть False
, если нет:
class BetterMaps(Maps):
def __enter__(self):
try:
self.data_dne = False
return self
except (NoMapsHereError, AssertionError):
self.data_dne = True
return False
def __exit__(self, type, value, traceback):
if self.data_dne:
pass
else:
self.data.close()
with BetterMaps(name, releaseversion) as bettermaps:
if not bettermaps:
pass
else:
do_work_here(bettermaps)
с намерением, что в случае сбоя установки (данные не могутне будет загружен), bettermaps
будет принимать значение False
, которое будет обходить do_work_here()
.Это не работает, и AssertionError
все еще поднят.Разве ошибки, возникающие в __init__
, не подчиняются логике в __enter__
?
В более широком смысле, есть ли предпочтительный способ обработки случаев, когда что-то в __init__
ломается?Я понимаю, что в моем случае я мог попытаться восстановить имя файла, к которому осуществляется доступ, и остановиться, если файл не существует;но я бы настоятельно предпочел бы не делать этого, так как это усложнит мою кодовую базу.Обратная связь приветствуется.