gpt4 book ai didi

python - 包装python dict时保持引用

转载 作者:太空宇宙 更新时间:2023-11-04 04:55:14 27 4
gpt4 key购买 nike

我想在 python3 中编写一个 dict 子类,它包装了一些 dict 方法并返回同一类的实例而不是 __getitem__ 上的 dict,如果请求的值恰好是一个 dict .否则,我希望有与 dict 完全相同的行为。这是我想出的:

class WrappedDict(dict):
def __init__(self, stuff, *args, **kwargs):
super(WrappedDict, self).__init__(*args, **kwargs)
self.stuff = stuff

def update_stuff(self):
pass # Do things with stuff

def update(self, *args, **kwargs):
self.update_stuff(*args, **kwargs)
super(WrappedDict, self).update(*args, **kwargs)

def __getitem__(self, item):
obj = super(WrappedDict, self).__getitem__(item)
if isinstance(obj, dict):
return WrappedDict(self.stuff + str(item), obj)
else:
return obj

然而,这与 dict 不同,因为它不返回对 dict 值的引用,而是从该 dict 创建的新对象。为了说明我的意思:

d1 = {'a': 1, 'b': 2, 'c': {'d': 4}}
d1.update(a=10)
d2 = d1['c']
d2.update(d=40)
print(d1)

会给出:

{'a': 10, 'b': 2, 'c': {'d': 40}}

但对 WrappedDict 做同样的事情:

wd1 = WrappedDict("stuff", {'a': 1, 'b': 2, 'c': {'d': 4}})
wd1.update(a=10)
wd2 = wd1['c']
wd2.update(d=40)
print(wd1)

给出:

{'a': 10, 'b': 2, 'c': {'d': 4}}

在内部字典中注释 4 而不是预期的 40。有没有一种方法可以在不使用太多黑魔法的情况下复制以前的行为?

最佳答案

使用 __setitem__ 将新创建的 WrappedDict 设置回您的对象:

def __getitem__(self, item):
obj = super(WrappedDict, self).__getitem__(item)
if isinstance(obj, dict):
wrapped = WrappedDict(self.stuff + str(item), obj)
super(WrappedDict, self).__setitem__(item, wrapped)
return wrapped
else:
return obj

完整代码:

class WrappedDict(dict):
def __init__(self, stuff, *args, **kwargs):
super(WrappedDict, self).__init__(*args, **kwargs)
self.stuff = stuff

def update_stuff(self, *args, **kwargs):
pass # Do things with stuff

def update(self, *args, **kwargs):
self.update_stuff(*args, **kwargs)
super(WrappedDict, self).update(*args, **kwargs)

def __getitem__(self, item):
obj = super(WrappedDict, self).__getitem__(item)
if isinstance(obj, dict):
wrapped = WrappedDict(self.stuff + str(item), obj)
super(WrappedDict, self).__setitem__(item, wrapped)
return wrapped
else:
return obj

d1 = {'a': 1, 'b': 2, 'c': {'d': 4}}
d1.update(a=10)
d2 = d1['c']
d2.update(d=40)
print(d1)

wd1 = WrappedDict("stuff", {'a': 1, 'b': 2, 'c': {'d': 4}})
wd1.update(a=10)
wd2 = wd1['c']
wd2.update(d=40)
print(wd1)

输出:

{'a': 10, 'b': 2, 'c': {'d': 40}}
{'a': 10, 'b': 2, 'c': {'d': 40}}

关于python - 包装python dict时保持引用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47236462/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com