Python: класс с возможностью подписки

#design-patterns #python-3.x #metaclass

#шаблоны проектирования #python-3.x #метакласс

Вопрос:

My class Item описывает определенные элементы, которые, естественно, известны по их числовому идентификатору (0, 1, 2, …). Я внедрил реестр внутри класса, который индексирует все объекты по их идентификатору. У меня также есть метод, который извлекает объект по его идентификатору:

 class Item
    _registry = []
    def __init__(self):
        self._registry.append(self)
        # ...
    @classmethod
    def get_item_by_id(cls, k):
        return cls._registry[k]
    # ...
  

Является ли это разумным дизайном?

Предполагая, что это так, было бы нормально разрешить индексы для Item самого класса? Я могу (я думаю) определить __getitem__ в Item метаклассе, что позволяет использовать синтаксис Item[2] вместо Item.get_item_by_id(2) .

Если у него есть какие-либо проблемы (например, слишком странный, может вызвать нежелательные побочные эффекты и т.д.), Пожалуйста, дайте мне знать.

Комментарии:

1. для этого __getitem__ и предназначен…

2. придирка: я думаю, что строка 4 должна гласить self.__class__._registry.append(self) , что более явно

Ответ №1:

Нет. Это совершенно нормально. Это определенно лучше, чем длинная форма. Просто убедитесь, что вы возвращаете разумные исключения ( KeyError с описательным сообщением, например Invalid id for element ), когда кто-то использует неправильный индекс. Кроме того, убедитесь, что вы задокументировали это поведение, иначе не было бы смысла вообще создавать объект с возможностью подписки.