Я работал над проблемой из небольшого сценария , который я написал. Это крюк между двумя приложениями. Проблема в том, что одно приложение было обновлено, и теперь оно использует yaml вместо json в качестве файла конфигурации.
Минимальный пример
import os
import yaml
import json
config = {
'version': "2.0.2",
'journals': {
"default": "/test/yaml/bhla"
},
'editor': os.getenv('VISUAL') or os.getenv('EDITOR') or "",
'encrypt': False,
'template': False,
'default_hour': 9,
'default_minute': 0,
'timeformat': "%Y-%m-%d %H:%M",
'tagsymbols': '@',
'highlight': True,
'linewrap': 79,
'indent_character': '|',
}
with open("jrnl.yaml", 'w') as f:
yaml.safe_dump(config, f, encoding='utf-8', allow_unicode=True, default_flow_style=False)
Это создаст файл yaml, в котором вы запустите код,
Проблема
Сначала я написал этот простой патч, чтобы мой хук мог работать с обоими (json и yaml).
JRNL_CONFIG_PATH = "jrnl.yaml"
with open(JRNL_CONFIG_PATH, "r") as f:
try:
JRNL_CONFIG = json.load(f)
except json.JSONDecodeError:
JRNL_CONFIG = yaml.load(f, Loader=yaml.FullLoader)
TAGS_SYMBOL = JRNL_CONFIG.get("tagsymbols", "@")
Но как большой сюрприз, когдаошибка поймана, f
закрыта, потому что JRNL_CONFIG
вернет None и выдаст эту ошибку:
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
<ipython-input-141-bc1ef847563b> in <module>()
----> 1 JRNL_CONFIG.get("tagsymbols", "@")
AttributeError: 'NoneType' object has no attribute 'get'
Вопросы
- Почему перехватывать исключение закрыть открытый файл, си без контекста?
- Каков наилучший способ отловить ошибку json и при этом иметь возможность анализировать файл как yaml?
Протестировано
- Не удается передать файл по имени, так как файл конфигурации может не иметь расширения (
.json
, .yaml
) - Эта работа, но она далека от элегантности ...
try:
f = open(JRNL_CONFIG_PATH, "r")
JRNL_CONFIG = json.load(f)
except json.JSONDecodeError:
f = open(JRNL_CONFIG_PATH, "r")
JRNL_CONFIG = yaml.load(f, Loader=yaml.FullLoader)
finally:
f.close()
Редактировать 1
Вопрос 1 : Зачем ловить исключение после открытияфайл с контекстом и без контекста?
Удостоверился в @ jedwards
Вопрос 2 : Что лучшеспособ отловить ошибку json и все еще иметь возможность проанализировать файл как yaml?
Был обработан @ chepner