Python - 有没有优雅的方式在从json对象提取数据时避免大量的try/except块?
我在寻找一些方法来写像 get_profile(js)
这样的函数,但不想用那些繁琐的 try/except 语句。
每次赋值都放在 try/except 里,因为有时候 json 字段可能不存在。如果能有一个优雅的解决方案,能把所有缺失的字段默认设置为 None
,那我会很满意。虽然我已经为一些字段设置了默认值,比如 []
等,但如果这样做能让整体代码看起来更简洁,那就更好了。
def get_profile(js):
""" given a json object, return a dict of a subset of the data.
what are some cleaner/terser ways to implement this?
There will be many other get_foo(js), get_bar(js) functions which
need to do the same general type of thing.
"""
d = {}
try:
d['links'] = js['entry']['gd$feedLink']
except:
d['links'] = []
try:
d['statisitcs'] = js['entry']['yt$statistics']
except:
d['statistics'] = {}
try:
d['published'] = js['entry']['published']['$t']
except:
d['published'] = ''
try:
d['updated'] = js['entry']['updated']['$t']
except:
d['updated'] = ''
try:
d['age'] = js['entry']['yt$age']['$t']
except:
d['age'] = 0
try:
d['name'] = js['entry']['author'][0]['name']['$t']
except:
d['name'] = ''
return d
5 个回答
8
- 使用字典的
get(key[, default])
方法。 - 这段代码可以生成一些基础代码,帮你省去更多麻烦。
8
把你所有的 try catch 代码块换成链式调用字典的 get(key [,default]) 方法。链中除了最后一次调用的 get 方法,前面的调用都应该设置默认值为 {}(空字典),这样后面的调用才能在一个有效的对象上进行。只有链中最后一次调用的 get 方法才应该使用你想查找的键的默认值。
想了解更多关于字典的信息,可以查看 Python 的官方文档:http://docs.python.org/library/stdtypes.html#mapping-types-dict
举个例子:
d['links'] = js.get('entry', {}).get('gd$feedLink', [])
d['published'] = js.get('entry', {}).get('published',{}).get('$t', '')
3
试试这样的做法...
import time
def get_profile(js):
def cas(prev, el):
if hasattr(prev, "get") and prev:
return prev.get(el, prev)
return prev
def getget(default, *elements):
return reduce(cas, elements[1:], js.get(elements[0], default))
d = {}
d['links'] = getget([], 'entry', 'gd$feedLink')
d['statistics'] = getget({}, 'entry', 'yt$statistics')
d['published'] = getget('', 'entry', 'published', '$t')
d['updated'] = getget('', 'entry', 'updated', '$t')
d['age'] = getget(0, 'entry', 'yt$age', '$t')
d['name'] = getget('', 'entry', 'author', 0, 'name' '$t')
return d
print get_profile({
'entry':{
'gd$feedLink':range(4),
'yt$statistics':{'foo':1, 'bar':2},
'published':{
"$t":time.strftime("%x %X"),
},
'updated':{
"$t":time.strftime("%x %X"),
},
'yt$age':{
"$t":"infinity years",
},
'author':{0:{'name':{'$t':"I am a cow"}}},
}
})
我有点冒险地假设你用的是一个字典,而不是一个列表,里面有一个键是0,不过... 你明白我的意思了。