#python #exception-handling #dictionary #python-2.4
#python #исключение #словарь #python-2.4
Вопрос:
Я пишу несколько сценариев, которые будут использоваться пользователями, не являющимися пользователями python. У меня есть класс конфигурации, в котором есть словари, и я хотел бы иметь возможность создавать пользовательское исключение для KeyError. Есть ли элегантный способ сделать это, кроме написания метода, который вызывает исключение при проверке значения в словаре?
Вот пример:
class ConfigError(Exception): pass
class Config:
def __init__(self):
self.cars = {'BMW': 'M5', 'Honda': 'Civic'}
def get_car(self, name):
try:
return self.cars[name]
except KeyError, e:
raise ConfigError("Car %s doesn't exist!!!" % name)
conf = Config()
print 'Car: %s' % conf.cars['BMW']
print 'Car: %s' % conf.cars['Mercedes']
Вот результат:
Car: M5
Traceback (most recent call last):
File "test.py", line 17, in ?
print 'Car: %s ' % conf.cars['Mercedes']
KeyError: 'Mercedes'
Я знаю, что могу написать метод, подобный Config.get_car() выше, и вызвать пользовательское исключение, но я хотел бы иметь возможность вызывать пользовательское исключение при прямой попытке доступа к словарю Config.cars. Я хотел бы сделать это, потому что в конфигурации на самом деле больше словарей, но мне нужно только создать пользовательское исключение для одного из словарей, и я хотел бы сохранить согласованность доступа к данным (все как словари).
Примечание: для этого используется Python 2.4.4
Ответ №1:
Подумайте об этом.
class MyConfigDict( dict ):
def __getitem__( self, key ):
try:
return super( MyConfigDict, self ).__getitem__( key )
except KeyError as e:
raise MyConfigError( e.message )
Что-то подобное может позволить вам обернуть каждый доступ в ваше собственное расширенное исключение.
Комментарии:
1. Могу ли я спросить, зачем использовать
super().__getitem__(key)
вместоself.__getitem__(key)
?2. Потому что рассматриваемый код является определяющим
self.__getitem__(key)
. Поведение, которое мы хотим, — это использовать поведение dict по умолчанию (iesuper().__getitem__(key)
и вызывать пользовательскую ошибку, если это не удается. Если бы мы вызывалиself.__getitem__(key)
, как предложено, мы бы вошли в рекурсивный цикл