Подклассы dict: должен ли вызываться dict .__ init __ ()?
Вот двойной вопрос, с теоретической и практической частью:
Когда подклассы диктуют:
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, потому что я бы использовал синтаксис db […] довольно часто (вместо того, чтобы делать db.contents […] все время); единственные данные объекта (атрибут) действительно действительно диктат. Я хочу добавить несколько методов в базу данных (например,get_image_by_name()
, или жеget_image_by_code()
, например), и только переопределить__init__()
потому что база данных изображений определяется каталогом, в котором она находится.
В итоге(практический) вопрос мог бы быть: что является хорошей реализацией для чего-то, что ведет себя как словарь, за исключением того, что его инициализация отличается (он принимает только имя каталога), и что у него есть дополнительные методы?
«Фабрики» были упомянуты во многих ответах. Так что я думаю, все сводится к тому: ты подкласс dict, переопределить__init__()
и добавить методы, или вы пишете (фабричная) функция, которая возвращает dict, к которой вы добавляете методы? Я склонен предпочесть первое решение, потому что функция фабрики возвращает объект, тип которого не указывает, что он имеет дополнительную семантику и методы, но что вы думаете?
Редактировать 2:
Из общего ответа я понимаю, что не стоит делать подкласс dict, когда новый класс «не словарь», и, в частности, когда его класс__init__
метод не может принимать те же аргументы, что и dict's__init__
(что имеет место в «практическом вопросе» выше). Другими словами, если я правильно понимаю, консенсус выглядит так: когда вы создаете подкласс, все методы (включая инициализацию) должны иметь ту же сигнатуру, что и методы базового класса. Это позволяет isinstance (subclass_instance, dict) гарантировать, чтоsubclass_instance.__init__()
можно использовать какdict.__init__()
, например.
Затем возникает другой практический вопрос: как реализовать класс, аналогичный dict, за исключением метода инициализации? без подклассов? это потребовало бы некоторого надоедливого стандартного кода, не так ли?