TypeError:尽管调用了TypeError异常,仍会返回NoneType

时间:2016-01-27 22:03:02

标签: python typeerror

我在嵌套字典中搜索键并返回值。我已使用多个例外行设置每个搜索,如下所示:

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'

但这对我来说似乎是一个重复,我哪里错了?

3 个答案:

答案 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"