【发布时间】:2017-07-25 11:30:16
【问题描述】:
我正在尝试实现从字典继承的简单树类。 这是我的代码:
class tree(dict):
def __init__(self, hsymbol="/"):
self.hsymbol = hsymbol
def __setitem__(self, key, value):
if key[0] == self.hsymbol : key = key[1:]
parts = key.split(self.hsymbol, 1)
if len(parts) == 2:
if parts[0] not in self: self[parts[0]] = tree(hsymbol = self.hsymbol)
self[parts[0]].__setitem__(parts[1], value)
else:
super(tree, self).__setitem__(key, value)
def __getitem__(self, key):
if key[0] == self.hsymbol : key = key[1:]
parts = key.split(self.hsymbol, 1)
if len(parts) == 2:
if parts[0] not in self: raise KeyError(parts[0])
return self[parts[0]][parts[1]]
else:
if key not in self: raise KeyError(parts[0])
return super(tree, self).__getitem__(key)
def __contains__(self,key):
if key[0] == self.hsymbol : key = key[1:]
parts = key.split(self.hsymbol, 1)
if len(parts) == 2:
if not super(tree, self).__contains__(parts[0]): return False
return parts[1] in self[parts[0]]
else:
if not super(tree, self).__contains__(key): return False
return True
def __delitem__(self, key):
if key[0] == self.hsymbol : key = key[1:]
parts = key.split(self.hsymbol, 1)
if len(parts) == 2:
if parts[0] not in self: raise KeyError(parts[0])
self[parts[0]].__delitem__(parts[1])
else:
if key not in list(self): raise KeyError(parts[0])
super(tree,self).__delitem__(key)
def keys(self,parent=""):
#if parent is None: parent = self.hsymbol
names = []
for name in super(tree, self).keys():
if isinstance(self[name], tree):
names += self[name].keys(parent=parent+self.hsymbol+name)
else:
names.append(parent+self.hsymbol+name)
return names
所以一切都很好,虽然我不确定按键功能的实现:
>>> t=tree()
>>> t['/user/Johnson/incoming'] = 2200
>>> t['/user/Johnson/family'] = 4
>>> t['/user/Johnson/play'] = False
>>> t['/user/Smith/incoming'] = 12000
>>> t['/user/Smith/family'] = 1
>>> t['/user/Smith/play'] = True
>>> t['user/Smith/incoming']
12000
>>> print t
{'user': {'Smith': {'play': True, 'incoming': 12000, 'family': 1}, 'Johnson': {'play': False, 'incoming': 2200, 'family': 4}}}
>>> print t.keys()
['/user/Smith/play', '/user/Smith/incoming', '/user/Smith/family', '/user/Johnson/play', '/user/Johnson/incoming', '/user/Johnson/family']
>>> t
{'user': {'Smith': {'play': True, 'incoming': 12000, 'family': 1}, 'Johnson': {'play': False, 'incoming': 2200, 'family': 4}}}
...但不是通过它的迭代:
>>> for k in t:
... print k
...
user
>>>
我怎样才能得到这样的东西?
/user/Smith/play
/user/Smith/incoming
/user/Smith/family
/user/Johnson/play
/user/Johnson/incoming
/user/Johnson/family
很确定一定是树类的__iter__和next属性,不过还没想好怎么写。
我搜索过 Stack Overflow 没有运气:
python 递归迭代嵌套字典
通过嵌套字典从字典迭代继承的python类
通过嵌套字典进行python迭代
【问题讨论】:
-
在问题的初始版本中抱怨 dupehammer 持有者并不是建立……富有成效的工作关系的好方法。请记住,如果您的问题确实被关闭,那些无需其他四个选民同意就可以重新打开它的人?还有那些有徽章的。所以。 如果您的问题以您认为不重复的内容结束,请论证当时如何区分它;不要预先设置敌对立场。
-
因为你继承自
dict,所以当你遍历你正在调用dict.__iter__的实例时;您的自定义keys方法将被忽略。考虑组合,而不是继承;实现MutableMappingABC,将包装好的字典作为属性。参见例如stackoverflow.com/a/3387975/3001761 -
@CharlesDuffy 但我只是厌倦了要求例如做一些没有功能的事情,并且得到它是重复的,所有事情都是由函数完成的......看看这个link...... .
-
或者,将
__iter__实现为return iter(self.keys())。 -
如果这个问题作为重复而被关闭,并且如果,在你实际尝试了答案之后对您的特定用例进行了适当修改的副本并发现它们不能解决您的问题,然后编辑问题以具体说明它们如何不能解决问题。不能保证您的问题不是骗子,如果骗子有您需要的答案,为什么不想向您展示它?
标签: python dictionary