Python for循环/EAFP中的异常处理

Python for循环/EAFP中的异常处理,python,exception,exception-handling,coding-style,Python,Exception,Exception Handling,Coding Style,我有一个带有JSON数据的请求,它可能包含也可能不包含'items'键,如果包含,它必须是我想要单独处理的对象列表。所以我必须写一些东西,比如: json_data = request.get_json() for item in json_data['items']: process_item(item) 但是,由于存在“items”键不是强制性的,因此需要采取额外的措施。我想遵循这种方法,所以将其包装成try。。。除声明外: json_data = request.get_json

我有一个带有JSON数据的请求,它可能包含也可能不包含
'items'
键,如果包含,它必须是我想要单独处理的对象列表。所以我必须写一些东西,比如:

json_data = request.get_json()
for item in json_data['items']:
    process_item(item)
但是,由于存在
“items”
键不是强制性的,因此需要采取额外的措施。我想遵循这种方法,所以将其包装成
try。。。除
声明外:

json_data = request.get_json()
try:
    for item in json_data['items']:
        process_item(item)
except KeyError as e:
    pass
让我们假设
KeyError
异常可能发生在
process\u item(…)
函数中,这可能表示代码错误,因此它不应该被忽略,因此我想确保我只捕获来自
for
语句谓词的异常,作为我提出的一种解决方法:

json_data = request.get_json()
try:
    for item in json_data['items']:
        process_item(item)
except KeyError as e:
    if e.message != 'items':
        raise e
    pass
但是

  • 它看起来很丑
  • 它依赖于
    process\u item(…)
    实现的知识,假设
    KeyError('items')
    不能在其内部提出
  • 如果
    for
    语句变得更复杂,例如
    对于json_数据['raw']['items']
    ,那么
    except
    子句也会变得更难阅读和维护
  • 更新: 建议的替代方案

    json_data = request.get_json()
    try:
        items = json_data["items"]
    except KeyError:
        items = []
    
    for item in items:
        process_item(item)
    
    本质上与

    json_data = request.get_json()
    if json_data.has('items')
        items = json_data['items']
    else:
        items = []
    
    for item in items:
        process_item(item)
    

    所以我们在循环之前检查一下。我想知道是否还有其他pythonic/EAFP方法?

    只有在访问
    项目时才能捕获异常:

    但是,我们可以使用对函数的调用来替换try块,使其更干净:

    for item in request.get_json().get("items", []):
        process_item(item)
    

    我认为最干净的选择是使用
    try
    块,仅围绕尝试检索与
    'items'
    键关联的数据的代码:

    json_data = request.get_json()
    try:
        items = json_data['items']
    except KeyError:
        print "no 'items' to process"  # or whatever you want to...
    else:
        for item in items:
            process_item(item)
    

    此布局将允许您按照自己认为合适的方式清楚地分离错误处理。如果需要,您可以在
    for循环周围添加一个独立的
    try
    /
    ,除了

    get()方法不仅代码行更短,而且更不容易出错。有许多异常处理方案,每个方案都有自己的回退。特别是,在继续执行并捕获异常之前,您始终需要确保根据您认为的原因引发异常。考虑到这一点,首先避免异常总是安全的(尽管并非总是必要的)。@univerio它与防御样式相同,只有在检查列表是否可编辑时,您才迭代该列表。它没有什么问题,如果需要访问嵌套元素,我通常会执行如下操作:for items.get('key1',{})。get('key2',[]),但我想看看是否有更类似python/EAFP的方法。
    json_data = request.get_json()
    try:
        items = json_data['items']
    except KeyError:
        print "no 'items' to process"  # or whatever you want to...
    else:
        for item in items:
            process_item(item)