【发布时间】:2011-01-24 07:01:09
【问题描述】:
假设我有class,它使用了dict 的某些功能。我曾经在内部合成一个dict 对象并提供一些来自外部的访问,但最近考虑简单地继承dict 并添加一些我可能需要的属性和方法。这是一个好方法,还是我应该坚持作曲?
【问题讨论】:
标签: python inheritance composition dictionary
假设我有class,它使用了dict 的某些功能。我曾经在内部合成一个dict 对象并提供一些来自外部的访问,但最近考虑简单地继承dict 并添加一些我可能需要的属性和方法。这是一个好方法,还是我应该坚持作曲?
【问题讨论】:
标签: python inheritance composition dictionary
两者都不错,但我更喜欢继承,因为这意味着更少的代码(只要可读性总是好的)。
Dive into Python has a very relevant example.
在 Python 2.2 及之前的版本中,您不能直接从内置子类中继承,因此您必须使用组合。
class FileInfo(dict): "store file metadata" def __init__(self, filename=None): self["name"] = filename
- 第一个区别是您不需要导入 UserDict 模块,因为 dict 是内置数据类型并且始终可用。第二个是您直接从 dict 继承,而不是从 UserDict.UserDict 继承。
- 第三个区别是微妙但重要的。 由于 UserDict 内部的工作方式,它需要您手动调用其
__init__方法来正确初始化其内部数据结构。dict不能这样工作;它不是包装器,不需要显式初始化。
【讨论】:
继承经常被滥用。除非您的课程旨在用作具有额外功能的通用字典,否则我会说组合是要走的路。
保存转发调用通常不是选择继承的充分理由。
来自设计模式书:
对象组合优于类继承
理想情况下,您不必创建 新组件实现重用。你 应该可以得到所有 组装所需的功能 通过对象的现有组件 作品。但这很少是 情况下,因为可用的集合 组件永远不够丰富 在实践中。通过继承重用 使制造新组件变得更容易 可以与旧的组成。 继承和对象组合 因此一起工作。
不过,我们的经验是 设计师过度使用继承作为 重用技术和设计往往 通过使更可重用(和更简单) 更多地取决于对象组成。”
【讨论】:
您确实必须权衡您尝试做的事情的成本和范围。从dict 继承,因为您希望类似字典的行为快速简单,但容易受到限制,例如导致从您的类创建的对象不可散列。
例如,如果您需要序列化(即pickle)对象,但还需要类似字典的行为,那么显然您不能直接从dict 继承,您需要编写您希望实现的功能部分。
【讨论】:
isinstance(my_object, dict) 应该返回 True 还是 False?换句话说,如果您不小心将其中一个对象交给了想要dict 的东西,它是否应该愉快地尝试将其用作dict?可能不会,所以使用组合。
【讨论】: