2015-05-28 2 views
3

Я пытаюсь написать блок try/except, который объявляет две переменные, которые извлекают свои значения через ConfigParser. Проблема, с которой я сталкиваюсь, заключается в том, что возможно, что один или оба объявляемых значения могут отсутствовать в определенном разделе и должны быть установлены в None в таком случае. Я знаю, что я могу просто добавить значения под каждым конфигурационным файлом, однако не все конфиги согласованы в именах разделов, что превращается в очень утомительную задачу.Попробуйте/За исключением блока, объявляющего несколько значений

Есть ли лучший способ достичь следующего блока try/except, не разбивая их на два отдельных?

try: 
    ports = getCfgStr(sectName, 'ports') 
    terminal = getCfgStr(sectName, 'terminals') 
except KeyError: 
    # Need to set ports or terminal to None depending on which raised the KeyError 

Мой обходной путь решения:

try: 
    ports = getCfgStr(sectName, 'ports') 
except KeyError: 
    ports = None 

try: 
    terminals = getCfgStr(sectName, 'terminals') 
except KeyError: 
    terminals = None 
+0

Для тех, кто заинтересован, [PEP-463] (http://legacy.python.org/dev/peps/pep-0463/) решает эту проблему. – swenzel

+0

Почему один блок try/except неправилен: если 'ports' является тем, который генерирует' KeyError', вы даже не попытаетесь получить значение для 'terminal'. При написании блока 'try' каждая строка кода должна быть необходима только в том случае, если строки перед ней не создают исключение. – chepner

+0

Что такое 'getCfgStr'? –

ответ

2

Интересный вопрос!

Как об этом:

def lookup(param): 
    try: 
     return getCfgStr(sectName, param) 
    except KeyError: 
     return None 

ports = lookup('ports') 
terminal = lookup('terminals') 
+2

Хорошая точка! Функция может быть еще лучше, если значение по умолчанию передано как необязательный аргумент: '' 'def lookup (sectName, param, default = None): ...' '' –

2

Лучшее решение, чтобы сделать ваш getCfgStr функция способна принимать значения по умолчанию, которые он будет возвращать, если нет такой опции в разделе. Так что ваш код будет выглядеть следующим образом:

ports = getCfgStr(sectName, 'ports', None) 
terminal = getCfgStr(sectName, 'terminals', None) 

Если вы должны исключения использования, ваше решение в порядке.

+0

Моя функция 'getCfgStr' - это та, которая вызывает' KeyError 'исключение. Я фактически включаю глобальный файл конфигурации по умолчанию, который содержит значения по умолчанию для всех разделов и элементов, которые являются согласованными между всеми другими конфигурациями, однако, как я уже упоминал в моем вопросе, это странный случайный сценарий, когда разделы и элементы могут различаться, и как таковые, не добавляются в глобальную конфигурацию по умолчанию. – ILostMySpoon

0

Может просто сделать функцию:

def get_or_default(name, default): 
    try: 
     result = getCfgStr(sectName, name) 
     return result 
    except KeyError: 
     return default 

вызова, как это:

ports = get_or_default('ports', None) 

Однако лучший подход, если вы используете ConfigParser бы изменить функцию getCfgStr использовать библиотеки путь делая это: https://docs.python.org/3.4/library/configparser.html#fallback-values

0

Вместо использования анти-шаблона coding by exception вы можете явно проверить i е опция присутствует:

RawConfigParser.has_option(section, option) 

Если данный раздел существует, и содержит данную опцию, возвращать True; иначе верните False.

Смежные вопросы