Вот двойной вопрос, с теоретической и практической:
Когда подклассы диктуют:
class ImageDB(dict):
def __init__(self, directory):
dict.__init__(self) # Necessary??
...
следует назвать dict.__init__(self)
, просто как «меру безопасности» (например, если есть какие-то нетривиальные детали реализации, которые имеют значение)? есть ли риск, что код порвется с будущей версией Python, если dict.__init__()
называется , а не ? Я ищу фундаментальную причину для того, чтобы делать одно или другое здесь (практически, вызов dict.__init__()
безопасен).
Я предполагаю, что когда вызывается ImageDB.__init__(self, directory)
, self уже является новым пустым объектом dict, и поэтому нет необходимости вызывать dict.__init__
(сначала я хочу, чтобы dict был пустым). Это правильно?
Редактировать
Более практический вопрос, стоящий за основополагающим вопросом выше, заключается в следующем. Я думал о подклассе dict, потому что я бы использовал синтаксис db […] довольно часто (вместо того, чтобы делать db.contents […] все время); единственные данные объекта (атрибут) действительно действительно диктат. Я хочу добавить несколько методов в базу данных (например, get_image_by_name()
или get_image_by_code()
) и переопределить только __init__()
, поскольку база данных изображений определяется каталогом, в котором она содержится.
В итоге , (практический) вопрос может быть: что является хорошей реализацией для чего-то, что ведет себя как словарь, за исключением того, что его инициализация отличается (он принимает только имя каталога), и что у него есть дополнительные методы?
«Фабрики» упоминались во многих ответах. Так что я думаю, все сводится к следующему: вы подкласс dict, переопределяете __init__()
и добавляете методы, или вы пишете (фабричную) функцию, которая возвращает dict, к которой вы добавляете методы? Я склонен предпочесть первое решение, потому что функция фабрики возвращает объект, тип которого не указывает на наличие у него дополнительной семантики и методов, но как вы думаете?
Редактировать 2 :
Из всех ответов я понимаю, что не следует делать подкласс dict, когда новый класс "не является словарем", и, в частности, когда его метод __init__
не может принимать те же аргументы, что и у dict __init__
(который это случай в «практическом вопросе» выше). Другими словами, если я правильно понимаю, консенсус выглядит так: когда вы создаете подкласс, все методы (включая инициализацию) должны иметь одинаковую сигнатуру с методами базового класса. Это позволяет isinstance (subclass_instance, dict) гарантировать, что subclass_instance.__init__()
можно использовать, например, dict.__init__()
.
Затем возникает другой практический вопрос: как реализовать класс, аналогичный dict, за исключением метода инициализации? без подклассов? для этого потребуется какой-нибудь надоедливый шаблонный код, не так ли?