这可能听起来很愚蠢。当我在python中覆盖dict时:
class idict(dict):
def __init__ (self, *args, **kwargs):
self._store = dict(*args, **kwargs)
然后我用
a = {1:2, 2:3}
b=idict(a)
print b._store == a
给出True
我不知道为什么dict(dict)
获得相同的词典。在python中的dict有任何方法处理这个吗?我不确定我是否以正确的方式做到了。
这个问题的另一个问题是:
如果我知道我将获得父类实例(如dict),我想在此实例中添加/更改方法。我通常从父类创建子类并获取子类实例。这似乎是内存效率低下的,因为父实例已经存在。
我搜索后的一种方法是直接在父类中添加/更改方法(例如parent_class.method = new_method
),然后获取父类的实例。我不确定这在OOP方面是否正确。
答案 0 :(得分:5)
它没有得到相同的dict
。它会对原始dict
进行浅层复制,而==
则按值进行比较,而不是按身份进行比较,因为它具有所有相同的键和值,它相等,即使它不是相同的 dict
。
如果您测试了print b._store is a
,那么您将获得False
,因为is
会测试对象标识。
至于你的另一个问题,我并不是100%确定你在那里做什么,但我认为你反对这样一个事实,即你并没有从继承中获益来自dict
,因为您仍然拥有存储所有值的属性。这只是因为你在这里没有正确地进行继承。您必须委托父类的方法,而不是制作自己的_store
属性,并且您将重用父级的存储。例如,这里正确的__init__
将是:
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) # On Py2 super(idict, self) needed instead of super()
现在你根本没有_store
,你通过将工作传递给链来初始化父类存储。
旁注:从技术上讲,正确的__init__
将是:
def __init__(*args, **kwargs):
if not args:
raise TypeError("descriptor '__init__' of 'Counter' object "
"needs an argument")
self = args[0]
if len(args) > 2:
raise TypeError('expected at most 1 arguments, got %d' % len(args))
super(idict, self).__init__(*args[1:], **kwargs)
这是一种特殊情况,仅适用于接受任意关键字的方法,您需要检测并正确响应调用者可能在不引发异常的情况下传递self=someval
的可能性(例如,在{ {1}},dict
是合法的)。像dict(self="abc")
这样的Python dict
子类使用这种技术。