如何通过点(dot)来获得字典的属性?

2016-02-04 11:19:56 +08:00
 billgreen1

现在用的是 dict of dict 的方式来表达数据。嵌套层次大概 3-4 层这样。

{
    'CatagoryA': {
                           'sub_catagory1':{
                                                       'sub_sub_catagory1':{},
                                                       ...
                                                     },
                           ...
                        },
    'CatagoryB':{
                         ...
                       },
     ...

}

不方便的地方在于记不住键。

我能想到的处理方法是把每个字典换做用一个类,然后用类嵌套类的方式来实现。
这样可以比较方便的用代码提示功能。

希望能有更好的办法。谢谢。

3275 次点击
所在节点    Python
6 条回复
Karblue
2016-02-04 11:42:30 +08:00
大概只能这么做。
```python
class MyDict(dict):
__getattribute__ = __getitem__
```
onlyice
2016-02-04 11:43:40 +08:00
@Karblue 你没看清楚楼主的要求,他希望的是 IDE 能够给自动提示
hahastudio
2016-02-04 11:49:20 +08:00
重写 __getattr__ __setattr__
http://stackoverflow.com/questions/2352181/how-to-use-a-dot-to-access-members-of-dictionary
http://code.activestate.com/recipes/576586-dot-style-nested-lookups-over-dictionary-based-dat/

用函数去接受这种特殊的查询字符串
http://stackoverflow.com/questions/12414821/checking-a-dictionary-using-a-dot-notation-string

但是你要注意,你的 key 永远都不能有 dot 了,所以其实是不等价的
至于你说的代码提示,不知道这种方式会不会有提示,估计没有
--话说为什么要用 js 的方式去写 Python ,这又不是 json--
Karblue
2016-02-04 11:54:39 +08:00
@onlyice 好吧~没看清。 LZ 可以试试 Pycharm 大部分提示可以搞定。包括手动赋值的 dict
lianghui
2016-02-04 12:04:02 +08:00
```python
class SelectConfig(object):

def __init__(self, config=None):
self._config = config or {}

def set(self, key, value):
keys = self._keys(key)
config = self._config
i = 0
for k in keys:
if isinstance(config, dict) and k in config:
if i == len(keys) - 1:
config[k] = value
return
config = config[k]
i += 1

keys = keys[i:]
last_key = keys.pop()
for k in keys:
config[k] = {}
config = config[k]
config[last_key] = value

def get(self, key=None, default=None):
keys = self._keys(key)
config = self._config
for k in keys:
if k in config:
config = config[k]
else:
config = default
break

return config

def delete(self, key):
keys = self._keys(key)
if len(keys) == 2:
v = self.get(keys[0])
if isinstance(v, dict):
del v[keys[1]]
else:
del self._config[keys[0]]

def update(self, config):
for k, v in config.items():
self.set(k, v)

def __contains__(self, key):
keys = self._keys(key)
contains = True
config = self._config
for k in keys:
if k in config:
config = config[k]
else:
contains = False
break

return contains

def _keys(self, key):
return key.split('.')

def __json__(self):
return self._config
```
Anthony117
2016-02-04 19:39:35 +08:00
```python
class Dict(dict):
'''
Simple dict but support access as x.y style.
'''
def __init__(self, d):
super(Dict, self).__init__()
for k, v in d.items():
self[k] = Dict(v) if isinstance(v, dict) else v

def __getattr__(self, key):
try:
return self[key]
except KeyError:
raise AttributeError(r"'Dict' object has no attribute '%s'" % key)

def __setattr__(self, key, value):
self[key] = value
```

使用:
```python
>>> dic = Dict({'a':1,'b':2})
>>> dic.b
2
```


修改自廖雪峰的 python 教程:
http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/001432339034336cbf72acd43354d72831461e3871d9f2e000

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/255344

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX