我发现访问dict密钥更加方便,obj.foo而不是obj['foo'],所以我写了这个代码片段:
class AttributeDict(dict):
def __getattr__(self, attr):
return self[attr]
def __setattr__(self, attr, value):
self[attr] = value
Run Code Online (Sandbox Code Playgroud)
但是,我认为必须有一些原因,Python不提供开箱即用的功能.以这种方式访问dict密钥有什么警告和陷阱?
如何通过点"."访问Python字典成员?
例如,mydict['val']我不想写作,而是写作mydict.val.
此外,我想以这种方式访问嵌套的dicts.例如
mydict.mydict2.val
Run Code Online (Sandbox Code Playgroud)
会参考
mydict = { 'mydict2': { 'val': ... } }
Run Code Online (Sandbox Code Playgroud) 我希望能够做到这样的事情:
from dotDict import dotdictify
life = {'bigBang':
{'stars':
{'planets': []}
}
}
dotdictify(life)
# This would be the regular way:
life['bigBang']['stars']['planets'] = {'earth': {'singleCellLife': {}}}
# But how can we make this work?
life.bigBang.stars.planets.earth = {'singleCellLife': {}}
#Also creating new child objects if none exist, using the following syntax:
life.bigBang.stars.planets.earth.multiCellLife = {'reptiles':{},'mammals':{}}
Run Code Online (Sandbox Code Playgroud)
我的动机是改进代码的简洁性,如果可能的话,使用与Javascript类似的语法来访问JSON对象,以实现高效的跨平台开发.(我也使用Py2JS和类似的.)
我已经开始使用这样的结构:
class DictObj(object):
def __init__(self):
self.d = {}
def __getattr__(self, m):
return self.d.get(m, None)
def __setattr__(self, m, v):
super.__setattr__(self, m, v)
Run Code Online (Sandbox Code Playgroud)
更新:基于这个线程,我已经将DictObj实现修改为:
class dotdict(dict):
def __getattr__(self, attr):
return self.get(attr, None)
__setattr__= dict.__setitem__
__delattr__= dict.__delitem__
class AutoEnum(object):
def __init__(self):
self.counter = 0
self.d = {}
def __getattr__(self, c):
if c not in self.d:
self.d[c] = self.counter
self.counter += 1
return self.d[c]
Run Code Online (Sandbox Code Playgroud)
其中DictObj是一个可以通过点表示法访问的字典:
d = DictObj()
d.something = 'one'
Run Code Online (Sandbox Code Playgroud)
我发现它比美学更令人愉悦d['something'].请注意,访问未定义的键会返回None而不是引发异常,这也很好.
更新:Smashery提出了一个很好的观点,mhawke扩展了更容易的解决方案.我想知道使用dict是否有任何不良副作用,而不是定义一个新字典; 如果没有,我很喜欢mhawke的解决方案.
AutoEnum是一个自动递增的枚举,使用如下:
CMD = AutoEnum()
cmds = …Run Code Online (Sandbox Code Playgroud) 我正在构建一些Python代码来读取和操作深层嵌套的dicts(最终用于与JSON服务进行交互,但是出于其他目的它会很棒)我正在寻找一种方法来轻松读取/设置/更新内部值dict,不需要很多代码.
@see还有Python:通过属性递归访问dict以及索引访问? - Curt Hagenlocher的"DotDictify"解决方案非常有说服力.我也喜欢Ben Alman在http://benalman.com/projects/jquery-getobject-plugin/中为JavaScript提供的内容. 将两者结合起来会很棒.
在Curt Hagenlocher和Ben Alman的例子的基础上,拥有如下功能的Python会很棒:
>>> my_obj = DotDictify()
>>> my_obj.a.b.c = {'d':1, 'e':2}
>>> print my_obj
{'a': {'b': {'c': {'d': 1, 'e': 2}}}}
>>> print my_obj.a.b.c.d
1
>>> print my_obj.a.b.c.x
None
>>> print my_obj.a.b.c.d.x
None
>>> print my_obj.a.b.c.d.x.y.z
None
Run Code Online (Sandbox Code Playgroud)
知道这是否可行,如果可行,如何修改DotDictify解决方案?
或者,可以使get方法接受点符号(并添加补充集方法)但是对象符号确定更清晰.
>>> my_obj = DotDictify()
>>> my_obj.set('a.b.c', {'d':1, 'e':2})
>>> print my_obj
{'a': {'b': {'c': {'d': 1, 'e': 2}}}}
>>> print my_obj.get('a.b.c.d')
1
>>> print my_obj.get('a.b.c.x')
None
>>> print my_obj.get('a.b.c.d.x')
None …Run Code Online (Sandbox Code Playgroud) 我在python中使用argparse来解析命令行参数:
parser = ArgumentParser()
parser.add_argument("--a")
parser.add_argument("--b")
parser.add_argument("--c")
args = parser.parse_args()
Run Code Online (Sandbox Code Playgroud)
现在我想要做一些计算用a,b和c.但是,我发现一直写的很烦人args.a + args.b + args.c.
因此,我正在提取这些变量:
a, b, c = [args.a, args.b, args.c]
Run Code Online (Sandbox Code Playgroud)
这样我就可以写了a + b + c.
有更优雅的方式吗?
添加许多参数时,手动提取变得非常繁琐且容易出错.
我有一个实用程序类,使得Python字典在获取和设置属性方面的行为有点像JavaScript对象.
class DotDict(dict):
"""
a dictionary that supports dot notation
as well as dictionary access notation
usage: d = DotDict() or d = DotDict({'val1':'first'})
set attributes: d.val2 = 'second' or d['val2'] = 'second'
get attributes: d.val2 or d['val2']
"""
__getattr__ = dict.__getitem__
__setattr__ = dict.__setitem__
__delattr__ = dict.__delitem__
Run Code Online (Sandbox Code Playgroud)
我想这样做它也将嵌套的字典转换成DotDict()实例.我希望能够做这样的事有__init__或__new__,但我还没有拿出任何的工作原理:
def __init__(self, dct):
for key in dct.keys():
if hasattr(dct[key], 'keys'):
dct[key] = DotDict(dct[key])
Run Code Online (Sandbox Code Playgroud)
如何递归地将嵌套字典转换为DotDict()实例?
>>> dct = {'scalar_value':1, 'nested_dict':{'value':2}}
>>> dct = DotDict(dct)
>>> print dct
{'scalar_value': …Run Code Online (Sandbox Code Playgroud) 这是我正在考虑使用的模式:
class Dicty(dict):
def __init__(self):
self.__dict__ = self
d = Dicty()
d.foo = 'bar'
print d['foo']
>>> bar
d['foo'] = 'baz'
print d.foo
>>> 'baz'
Run Code Online (Sandbox Code Playgroud)
一般来说,我更喜欢对象属性访问的语义而不是dict get/set访问,但是在某些情况下需要类似dict的访问(例如d['foo-bar'] = 'baz'),我宁愿不为这些情况使用特殊的getter setter方法,因此,dict和object同时具有共享属性的双重行为.
有上述模式的问题吗?
python ×8
dictionary ×4
coding-style ×2
syntax ×2
argparse ×1
getattr ×1
nested ×1
oop ×1
recursion ×1