Skip to main content
 首页 » 编程设计

python之为什么 dict(dict) 得到相同的字典

2025年05月04日23lautakyan007

这听起来可能很愚蠢。当我在 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有什么方法可以处理这个吗?我不确定我的做法是否正确。

这个问题的另一个问题:

如果我知道我会得到一个父类实例(如字典),我想在这个实例中添加/更改方法。我通常从父类创建子类并获取子类实例。这似乎内存效率低下,因为父实例已经存在。

我搜索后的一种方法是直接在父类中添加/更改方法(例如 parent_class.method = new_method),然后获取父类的实例。我不确定这在 OOP 方面是否正确。

请您参考如下方法:

它没有得到相同的 dict。它正在对原始 dict 进行浅拷贝,并且 == 按值进行比较,而不是按身份进行比较,因此因为它具有所有相同的键和值,所以它是相等的,甚至虽然它不是相同 dict。

如果您测试了 print b._store is a,您将得到 False,因为 is 测试对象身份。

至于你的其他问题,我不是 100% 确定你在那里做什么,但我认为你反对这样一个事实,即你没有从 dict 的继承中受益>,因为您仍然有一个存储所有值的属性。那只是因为你没有在这里正确地进行继承。您必须委托(delegate)给父类的方法,而不是创建您自己的 _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 而不引发异常的可能性(例如对于 dict,dict(self="abc") 是合法的)。 Python dict 子类,如 collections.Counter 使用这种技术。