如何改变一个实例的dict()的行为 [英] How to change behavior of dict() for an instance
问题描述
from collections import defaultdict
class RecursiveDict(defaultdict):
'''
一个递归默认的dict。
>>> a = RecursiveDict()
>>>> a [1] [2] [3] = 4
>>>> a.dictify()
{1:{2:{3:4}}}
'''
def __init __(self):
super(RecursiveDict,self) __init __(RecursiveDict)
def dictify(self):
'''获取树中项目的标准字典'''
return dict([(k, (v.dictify()if isinstance(v,dict)else v))
for(k,v)in self.items()])
def __dict __(self):
'''获取树中项目的标准字典''
print [(k,v)for(k,v)in self.items()]
return dict ()(b)()()()()()()()()
编辑:更清楚地显示问题:
>>> b = RecursiveDict()
>>> b [1] [2] [3] = 4
>>> b
defaultdict(< class'__main __。RecursiveDict'>,{1:defaultdict(< class'__main __。RecursiveDict'>,{2:defaultdict(< class'__main __。RecursiveDict' {3:4})})})
>>> dict(b)
{1:defaultdict(< class'__main __。RecursiveDict'>,{2:defaultdict(< class'__main __。RecursiveDict'> {3:4})})}
>>>> b.dictify()
{1:{2:{3:4}}}
我想要dict(b)与b.dictify()相同b
你的方法没有什么问题,但这是类似于Perl的Autovivification功能,它已经在Python中实现了这个问题。
class RecursiveDict(dict):
执行perl的自动修复功能。 $$ b $ _ $($)
try:
return dict .__ getitem __(self,item)
除了KeyError:
value = self [item ] = type(self)()
返回值
>>> a = RecursiveDict()
>>>> a [1] [2] [3] = 4
>>>> dict(a)
{1:{2:{3:4}}}
编辑
根据@Rosh Oxymoron的建议,使用 __缺少__
导致更简洁实现。需要Python> = 2.5
class RecursiveDict(dict):
执行perl的自动修复功能
def __missing __(self,key):
value = self [key] = type(self)()
返回值
So I'm writing a class that extends a dictionary which right now uses a method "dictify" to transform itself into a dict. What I would like to do instead though is change it so that calling dict() on the object results in the same behavior, but I don't know which method to override. Is this not possible, or I am I missing something totally obvious? (And yes, I know the code below doesn't work but I hope it illustrates what I'm trying to do.)
from collections import defaultdict
class RecursiveDict(defaultdict):
'''
A recursive default dict.
>>> a = RecursiveDict()
>>> a[1][2][3] = 4
>>> a.dictify()
{1: {2: {3: 4}}}
'''
def __init__(self):
super(RecursiveDict, self).__init__(RecursiveDict)
def dictify(self):
'''Get a standard dictionary of the items in the tree.'''
return dict([(k, (v.dictify() if isinstance(v, dict) else v))
for (k, v) in self.items()])
def __dict__(self):
'''Get a standard dictionary of the items in the tree.'''
print [(k, v) for (k, v) in self.items()]
return dict([(k, (dict(v) if isinstance(v, dict) else v))
for (k, v) in self.items()])
EDIT: To show the problem more clearly:
>>> b = RecursiveDict()
>>> b[1][2][3] = 4
>>> b
defaultdict(<class '__main__.RecursiveDict'>, {1: defaultdict(<class '__main__.RecursiveDict'>, {2: defaultdict(<class '__main__.RecursiveDict'>, {3: 4})})})
>>> dict(b)
{1: defaultdict(<class '__main__.RecursiveDict'>, {2: defaultdict(<class '__main__.RecursiveDict'>, {3: 4})})}
>>> b.dictify()
{1: {2: {3: 4}}}
I want dict(b) to be same as b.dictify()
Nothing wrong with your approach, but this is similar to the Autovivification feature of Perl, which has been implemented in Python in this question. Props to @nosklo for this.
class RecursiveDict(dict):
"""Implementation of perl's autovivification feature."""
def __getitem__(self, item):
try:
return dict.__getitem__(self, item)
except KeyError:
value = self[item] = type(self)()
return value
>>> a = RecursiveDict()
>>> a[1][2][3] = 4
>>> dict(a)
{1: {2: {3: 4}}}
EDIT
As suggested by @Rosh Oxymoron, using __missing__
results in a more concise implementation. Requires Python >= 2.5
class RecursiveDict(dict):
"""Implementation of perl's autovivification feature."""
def __missing__(self, key):
value = self[key] = type(self)()
return value
这篇关于如何改变一个实例的dict()的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!