
第一个规范的问题在于,Python无法告诉您
__getitem__,在处
my_obj.a.b.c.d,您是否下一步将继续沿着不存在的树进行 *** 作,在这种情况下,它需要使用一种
__getitem__方法返回一个对象,因此您不会被
AttributeError抛出,或者如果您想要一个值,则需要返回
None。
我认为,在每种情况下,您都应该期望它抛出
KeyError而不是返回
None。原因是您无法分辨是否
None表示“无钥匙”或“实际存储
None在该位置的人”。对于此行为,您所需要做的就是take
dotdictify,remove
marker和替换
__getitem__为:
def __getitem__(self, key): return self[key]
因为您真正想要的是
dictwith
__getattr__和
__setattr__。
可能有一种方法可以
__getitem__完全删除并说一些类似的内容
__getattr__ =dict.__getitem__,但是我认为这可能是过度优化的问题,如果您以后决定要
__getitem__像
dotdictify最初那样创建树,那么这将是一个问题,在这种情况下,您会更改为:
def __getitem__(self, key): if key not in self: dict.__setitem__(self, key, dotdictify()) return dict.__getitem__(self, key)
我不喜欢
marker原来的生意
dotdictify。路径支持
第二个规范(override
get()和
set())是,法线
dict的
get()*** 作与您描述的不同,甚至不包含
set(尽管其
setdefault()*** 作与 *** 作相反
get())。人们期望
get采用两个参数,如果找不到密钥,则第二个参数为默认值。
如果要扩展
__getitem__并
__setitem__处理点键符号,则需要修改
doctictify为:
class dotdictify(dict): def __init__(self, value=None): if value is None: pass elif isinstance(value, dict): for key in value: self.__setitem__(key, value[key]) else: raise TypeError, 'expected dict' def __setitem__(self, key, value): if '.' in key: myKey, restOfKey = key.split('.', 1) target = self.setdefault(myKey, dotdictify()) if not isinstance(target, dotdictify): raise KeyError, 'cannot set "%s" in "%s" (%s)' % (restOfKey, myKey, repr(target)) target[restOfKey] = value else: if isinstance(value, dict) and not isinstance(value, dotdictify): value = dotdictify(value) dict.__setitem__(self, key, value) def __getitem__(self, key): if '.' not in key: return dict.__getitem__(self, key) myKey, restOfKey = key.split('.', 1) target = dict.__getitem__(self, myKey) if not isinstance(target, dotdictify): raise KeyError, 'cannot get "%s" in "%s" (%s)' % (restOfKey, myKey, repr(target)) return target[restOfKey] def __contains__(self, key): if '.' not in key: return dict.__contains__(self, key) myKey, restOfKey = key.split('.', 1) target = dict.__getitem__(self, myKey) if not isinstance(target, dotdictify): return False return restOfKey in target def setdefault(self, key, default): if key not in self: self[key] = default return self[key] __setattr__ = __setitem__ __getattr__ = __getitem__测试代码:
>>> life = dotdictify({'bigBang': {'stars': {'planets': {}}}})>>> life.bigBang.stars.planets{}>>> life.bigBang.stars.planets.earth = { 'singleCellLife' : {} }>>> life.bigBang.stars.planets{'earth': {'singleCellLife': {}}}>>> life['bigBang.stars.planets.mars.landers.vikings'] = 2>>> life.bigBang.stars.planets.mars.landers.vikings2>>> 'landers.vikings' in life.bigBang.stars.planets.marsTrue>>> life.get('bigBang.stars.planets.mars.landers.spirit', True)True>>> life.setdefault('bigBang.stars.planets.mars.landers.opportunity', True)True>>> 'landers.opportunity' in life.bigBang.stars.planets.marsTrue>>> life.bigBang.stars.planets.mars{'landers': {'opportunity': True, 'vikings': 2}}欢迎分享,转载请注明来源:内存溢出
微信扫一扫
支付宝扫一扫
评论列表(0条)