Как вызвать сообщение об ошибке ключа пользовательского словаря

#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 по умолчанию (ie super().__getitem__(key) и вызывать пользовательскую ошибку, если это не удается. Если бы мы вызывали self.__getitem__(key) , как предложено, мы бы вошли в рекурсивный цикл