这是一个双重问题,其中包括理论部分和实际问题:
当将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 :
我从每个人的答案中得出结论,当新类“不是字典”时,尤其是当其__init__
方法不能接受与dict相同的参数时,对dict进行子类化不是一个好主意__init__
(在“实际问题”中就是这种情况)以上)。换句话说,如果我理解正确,那么共识似乎是:当您子类化时,所有方法(包括初始化)都必须具有与基类方法相同的签名。例如,这允许isinstance(subclass_instance,dict)保证subclass_instance.__init__()
可以像一样使用dict.__init__()
。
然后弹出另一个实际问题:如何实现与dict相似的类,除了其初始化方法外,如何实现?没有子类化?这将需要一些麻烦的样板代码,不是吗?
您可能应该dict.__init__(self)
在子类化时调用;实际上,您不知道dict中到底发生了什么(因为它是内置的),并且可能因版本和实现而异。不调用它可能会导致不当行为,因为您无法知道dict将其内部数据结构保存在何处。
顺便说一句,您没有告诉我们您 想做 什么。如果你想用字典(映射)行为的一类,而你并不真正需要的字典(例如,有没有做的代码isinstance(x, dict)
软件中的任何地方,因为它应该是),你可能会更好过是在使用UserDict.UserDict
或UserDict.DictMixin
如果你”重新使用python
<= 2.5,或者collections.MutableMapping
使用python> = 2.6。这些将为您的班级提供出色的字典行为。
编辑:我在另一条评论中读到,您没有重写dict的任何方法!然后,根本没有子类化的意义,那就不要这样做。
def createImageDb(directory):
d = {}
# do something to fill in the dict
return d
编辑2:您想从dicthtml" target="_blank">继承来添加新方法,但是您不需要重写任何方法。一个好的选择可能是:
class MyContainer(dict):
def newmethod1(self, args):
pass
def newmethod2(self, args2):
pass
def createImageDb(directory):
d = MyContainer()
# fill the container
return d
顺便说一句:您要添加什么方法?您确定要创建一个好的抽象吗?也许您最好使用一个定义所需方法的类,并在其内部使用“常规”字典。
工厂功能:http:
//en.wikipedia.org/wiki/Factory_method_pattern
这只是将实例的构造委托给函数的一种方法,而不是覆盖/更改其构造函数。
问题内容: 和之间的区别是什么,推荐使用哪一个?该文档似乎不赞成使用? 而且似乎UserDict会使用我的方法,而不是吗?给定我想要的自定义和功能,哪些方法真正对重写至关重要? 使用s时,我将必须实现所有方法,因为它没有提供默认实现? 我想做一个做两件事: 所有键和值 将一些值存储在SQLite数据库中 所以其中,并最好将允许我这样做吗? 问题答案: 如果您想要一个实际上包含数据的自定义集合,请子
问题内容: 我有这段代码: 当我运行该代码时,出现以下错误: TypeError:无法散列的类型:’dict’ 该错误的原因是什么,我该怎么解决? 问题答案: 从错误中,我推断这是一个字典(请参阅下面的repro)。字典不能被散列,因此不能用作另一个字典的键(或本身就是这个键!)。 您可能意思是或。如果这两种解决方案都不起作用,那么在有关什么类型和是什么以及它们包含什么的更多上下文中,我们将能够为
问题内容: 我有这段代码: 当我运行该代码时,出现以下错误: TypeError:无法散列的类型:’dict’ 该错误的原因是什么,我该怎么办才能解决? 问题答案: 从错误中,我推断出它是字典(请参阅下面的repro)。字典不能被散列,因此不能用作另一个字典的键(或本身就是该键!)。 您可能意思是或。如果这两种解决方案都不起作用,则可以通过更多上下文了解什么是类型以及它们包含什么,我们将能够为您提
基本概要 它的原理类似于词典,也就是说有专门的目录页来查找,它并不需要从第一页翻到第二页等等到最后,它只需要查看自己的目录即可 语法: d = {'abb':'12', 'dd':12} d['abb'] 其实类似于js中的对象 const a = { a1:func(){}, b:12, c:'12333' } a.a1 a['a1'] let b = 'b' a[b] 这就是j
描述 (Description) 方法str()生成字典的可打印字符串表示。 语法 (Syntax) 以下是str()方法的语法 - str(dict) 参数 (Parameters) dict - 这是字典。 返回值 (Return Value) 此方法返回字符串表示。 例子 (Example) 以下示例显示了str()方法的用法。 #!/usr/bin/python dict = {'Nam
描述 (Description) 方法len()给出了字典的总长度。 这将等于字典中的项目数。 语法 (Syntax) 以下是len()方法的语法 - len(dict) 参数 (Parameters) dict - 这是字典,需要计算其长度。 返回值 (Return Value) 此方法返回长度。 例子 (Example) 以下示例显示len()方法的用法。 #!/usr/bin/python