验证字典列表中元素正确格式的最佳实践

时间:2018-10-23 13:51:06

标签: python validation try-catch

我有一个字典列表,其中包含来自API的数据,并且想要遍历此列表,并验证每个键的数据格式是否正确。我有单独的函数可以实现此目的,但是我想将它们集成到一个整体函数中。

例如从这里:

validate_date = datetime.datetime.strptime(date, '%d-%m-%Y')
validate_name = isinstance(name, str)

对于这样的事情:

def validate_content(row):
    try:
        datetime.datetime.strptime(row[0], '%d-%m-%Y')
    except:
        raise ValueError('Incorrect date format detected')

    try:
        isinstance(row[1], str)
    except:
        raise ValueError('Incorrect name format detected')

很明显,这种语法是不正确的,有人可以告诉我验证此类多个字段的最佳解决方案吗?

样本数据(索引4和5应该抛出错误):

names_and_dates = [{'date': '10-10-2018', 'name': 'Monday'},
                   {'date': '11-10-2018', 'name': 'Tuesday'},
                   {'date': '12-10-2018', 'name': 'Wednesday'},
                   {'date': '13-10-2018', 'name': 'Thursday'},
                   {'date': '2018-10-14', 'name': 'Friday'},
                   {'date': '15-10-2018', 'name': 55}]

2 个答案:

答案 0 :(得分:1)

您快到了:

import datetime

def validate_content(row):
    try:
        datetime.datetime.strptime(row["date"], '%d-%m-%Y')
    except:
        raise ValueError('Incorrect date format detected: {}'.format( row["date"] ))

    if not  isinstance(row["name"], str):
        raise ValueError('Incorrect name format detected: {}'.format( row["name"] ))


names_and_dates = [{'date': '10-10-2018', 'name': 'Monday'},
                   {'date': '11-10-2018', 'name': 'Tuesday'},
                   {'date': 'Hello world', 'name': 'Tuesday'},
                   {'date': '12-12-2020', 'name': 55},
                   ]

for index, item in enumerate(names_and_dates):
    try:
        validate_content(item)
    except Exception as e:
        print("Error in item {}: {}".format(index, e))

输出:

Error in item 2: Incorrect date format detected: Hello world
Error in item 3: Incorrect name format detected: 55

答案 1 :(得分:1)

仅作一些较小的修改:

from datetime import datetime

def validate_content(row):
    try:
        datetime.strptime(row['date'], '%d-%m-%Y')
    except ValueError:
        raise ValueError('Incorrect date format detected')

    if not isinstance(row['name'], str):
        raise ValueError('Incorrect name format detected')
  1. 不是普通的except,而是except ValueError(如果字典中不包含'date'键,则不会捕获引发的异常;应该在其他地方处理)
  2. isinstance仅返回False,但如果实例不是str,则不会引发错误;用try/except包围它不会达到您想要的效果。

这在起作用:

names_and_dates = [{'date': '10-10-2018', 'name': 'Monday'},
                   {'date': '11-10-2018', 'name': 'Tuesday'},
                   {'date': '12-10-2018', 'name': 'Wednesday'},
                   {'date': '13-10-2018', 'name': 'Thursday'},
                   {'date': '2018-10-14', 'name': 'Friday'},
                   {'date': '15-10-2018', 'name': 55}]

for row in names_and_dates:
    try:
        validate_content(row)
        print('valid row {}'.format(row))
    except ValueError as e:
        print('invalid row {}\n  exception: {}'.format(row, e))

将输出:

valid row {'date': '10-10-2018', 'name': 'Monday'}
valid row {'date': '11-10-2018', 'name': 'Tuesday'}
valid row {'date': '12-10-2018', 'name': 'Wednesday'}
valid row {'date': '13-10-2018', 'name': 'Thursday'}
invalid row {'date': '2018-10-14', 'name': 'Friday'}
  exception: Incorrect date format detected
invalid row {'date': '15-10-2018', 'name': 55}
  exception: Incorrect name format detected