python: наследование или композиция

допустим, что у меня есть class, который использует некоторые функции dict. Я использовал композит a dict объект внутри и обеспечить некоторый доступ извне, но в последнее время думал о просто наследовании dict и добавление некоторых атрибутов и методов, которые могут потребоваться. Это хороший путь, или я должен придерживаться композиции?

4 ответов


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

переадресация экономии звонки обычно не достаточно хорошая причина для выбора наследство.

из книги шаблонов дизайна:

предпочтение композиции объекта над наследованием класса

В идеале вам не нужно создавать новые компоненты для повторного использования. Вы должны быть в состоянии получить все функциональность вам путем собирать существующие компоненты через объект состав. Но это редко дело в том, что набор доступен компоненты никогда не достаточно богаты на практике. Повторное использование по наследованию облегчает создание новых компонентов это может быть составлено со старыми. Наследование и состав объектов так работаем вместе.

тем не менее, наш опыт показывает, что дизайнеры злоупотребляют наследованием как повторное использование техники и конструкций часто сделано более многоразовым (и проще) в зависимости от состава объекта."

весь текст здесь: http://blog.platinumsolutions.com/node/129


вы действительно должны взвесить стоимость и объем того, что вы пытаетесь сделать. Наследование от dict потому что вы хотите, чтобы словарь-подобное поведение было быстрым и легким, но склонным к ограничениям, таким как причинение объектов, созданных из вашего класса, чтобы быть unhashable.

Так, например, если вам нужно сериализовать (т. е. pickle) объекты, но также хотят словарного поведения, то, очевидно, вы не можете наследовать непосредственно от dict и вам нужно будет составить части функциональность вы хотите, чтобы это произошло.


должны isinstance(my_object, dict) вернуть True или False? Другими словами, если вы случайно даете один из объектов тому, что хочет dict, если он беспечно попытается использовать его как dict? Наверное, нет, поэтому используйте композицию.


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

погружение в Python имеет очень актуальный пример.

на Python 2.2 и ранее вы не могли подкласс из встроенных модулей напрямую, поэтому вы had использовать состав.

class FileInfo(dict):                  
   "store file metadata"
   def __init__(self, filename=None): 
       self["name"] = filename
  1. первое отличие заключается в том, что вам не нужно импортировать модуль UserDict, так как dict является встроенным тип данных и всегда доступна. Во-вторых, вы наследуете от dict напрямую, а не от UserDict.UserDict.
  2. третье различие тонкое, но важное. из-за того, как UserDict работает внутри, он требует, чтобы вы вручную вызывали его __init__ метод правильной инициализации его внутренних структур данных. dict не работает так; это не обертка, и он не требует явной инициализации.