我在嵌套字典中搜索键并返回值。我已使用多个例外行设置每个搜索,如下所示:
try:
accounts_category = json_data['primaryTopic']['Accounts']['AccountCategory']
except (KeyError, TypeError) as e:
accounts_category = ''
一旦我完成了搜索,我将字符串和管道分隔符组合如下:
line = H + '|' + vn_id + '|' + sn_id + '|' + supplier_name + '\n'
但是,当我尝试组合变量时,我得到了一个TypeError。
TypeError: coercing to Unicode: need string or buffer, NoneType found
如果我添加if
语句,我的脚本可以运行:
try:
accounts_next_due_date = json_data['primaryTopic']['Accounts']['NextDueDate']
if accounts_next_due_date:
pass
else:
accounts_next_due_date = 'e'
except (KeyError, TypeError) as e:
accounts_next_due_date = 'e'
但这对我来说似乎是一个重复,我哪里错了?
答案 0 :(得分:3)
我听到你说的是你执行这段代码:
try:
accounts_category = json_data['primaryTopic']['Accounts']['AccountCategory']
except (KeyError, TypeError) as e:
accounts_category = ''
之后accounts_category
(或您以这种方式处理过的其他变量)是None
,而不是''
。
显然,这种情况正在发生,因为没有引发错误。相反,json_data['primaryTopic']['Accounts']['AccountCategory']
(或其他)实际上是None
(即原始JSON中的null
)。
避免这种情况的最简单方法是使用or
关键字添加默认值(如果值为“false-ish”),如下所示:
accounts_category = json_data['primaryTopic']['Accounts']['AccountCategory'] or ''
当您使用值时,您也可以这样做:
line = "%s|%s|%s|%s\n" % (H, vn_id, sn_id, supplier_name or '')
作为奖励,因为它似乎并没有真正引发错误,所以你可以摆脱所有try/except
样板。如果你仍然需要它,为了爱上帝,请写一个函数来做它而不是复制和粘贴代码无数次!例如:
def jsonfield(jsonobj, default, *names):
try:
for name in names:
jsonobj = jsonobj[name]
return jsonobj or default
except (TypeError, KeyError):
return default
accounts_category = json_field(json_data, "", "primaryTopic", "Accounts", "AccountCategory")
答案 1 :(得分:0)
在Python 2中,尝试使用None
连接unicode字符串会引发TypeError
:
>>> u'abcd' + None
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: coercing to Unicode: need string or buffer, NoneType found
这就是问题出现的地方。但根本原因是json_data
可以拥有一个None
值的密钥。这是一个简单的例子:
>>> import json
>>> data = json.loads('{"a": 1, "b": null}')
{u'a': 1, u'b': None}
>>> b = data['b']
>>> b is None
True
这不会导致引发任何异常,因此None
可以绑定到您用于构造line
字符串的一个或多个变量。你可以用这个解决它:
accounts_category = json_data['primaryTopic']['Accounts']['AccountCategory']
if accounts_category is None:
accounts_category = u''
您可以将其概括为函数,以便可以将其应用于JSON数据中的其他键。
此外,您可以使用str.join()
更好地执行字符串的连接:
line = u'|'.join((H, vn_id, sn_id, supplier_name)
答案 2 :(得分:-1)
accounts_next_due_date = None
try:
accounts_next_due_date = json_data['primaryTopic']['Accounts']['NextDueDate']
except (KeyError, TypeError):
pass # or log the error
finally:
if not accounts_next_due_date:
accounts_next_due_date = "e"