这是一个双重问题,一个理论部分,一个实践部分:
子类化dict时:
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一样的类应该如何实现?没有子类化?这需要一些麻烦的样板代码,不是吗?