在 Python 中验证数据类型



我正在拉入一个包含键值对的数据文件,其中数据是原始的,并以字符串开头。 我创建了这个函数来传递键值对的值以检查它是什么数据类型。

我创建了这个函数来标记该值,并根据需要将其转换为适当的数据类型。

这是处理这个问题的最佳方法,还是python中已经包含一个更快或更高效的库或函数?

import dateparser
def dataType(value):
try: 
int(value)
return 'INTEGER'
except ValueError:
try:
float(value)
return 'DOUBLE'
except ValueError:
try:
if value and value[0].isdigit():
dateparser.parse(value, settings={'STRICT_PARSING': True})
return 'DATETIME'
else: 
return 'VARCHAR'
except ValueError:
return 'VARCHAR'

你云做这样的事情:

import re
from collections import OrderedDict
import datetime
register_type = OrderedDict()

register_type["INTEGER"] = {"handle":int, "args": [], "kw": {}}
register_type["DOUBLE"] = {"handle":float, "args": [], "kw": {}}
register_type["DATE"] = {"handle":lambda x: datetime.datetime.strptime(x, "%Y-%m-%d"), "args": [], "kw": {}}
register_type["ALPHA"] = {"handle":lambda x: re.match("w+", x), "args": [], "kw": {}}

def get_type(value):
type_ = "UNKNOWN"
for k, v in register_type.items():
try:
parsed = v["handle"](value, *v["args"], **v["kw"])
type_ = k
break
except ValueError as E:
continue
return  type_


# print(get_type("2017-01-26"))
# "DATE"
# print(get_type("ali"))
# "alpha"
# print(get_type("10"))
# "INTEGER"
# print(get_type("10.0"))
# "DOUBLE"

通过这种方式,您可以轻松添加解析器,从而解耦代码。

使用arrow库轻松检测datetime类型。

@thefourtheye的回答让我得到了更多的启发,literal_eval将任何数据转换为适当的type

然后,我使用映射来转换所需的文本字符串找到的type

from ast import literal_eval
import arrow
map_type_to_string = {int: 'INTEGER',
bool: 'BOOLEAN',
str: 'VARCHAR',
float: 'DOUBLE',
arrow.arrow.Arrow: 'DATETIME'}
def get_type(input_data):
try:
return map_type_to_string[type(literal_eval(input_data))]
except (ValueError, SyntaxError):
try:
return map_type_to_string[type(arrow.get(input_data))]
except (arrow.parser.ParserError, ValueError):
return map_type_to_string[str]
print(get_type("1"))                              # INTEGER
print(get_type("1.2354"))                         # DOUBLE
print(get_type("True"))                           # BOOLEAN
print(get_type("2002-12-25 00:00:00-06:39"))      # DATETIME
print(get_type("abcd"))                           # VARCHAR

希望它有所帮助。

如果你想要一些内置于Python的东西(不需要模块),那么这可能会有一些用处。

get_type = lambda value: str(type(value)).split("'")[1]

这里发生的事情是,我们从内置类型函数中获取结果并将其转换为字符串以对其进行拆分,以便我们可以返回从该函数报告回来的数据类型。

以下是我从 Python 3 中的一些测试中收集到的内容:

>>> get_type(10)
'int'
>>> get_type('10')
'str'
>>> get_type(b'10')
'bytes'
>>> get_type(10.0)
'float'
>>> get_type(True)
'bool'

我希望我能更详细地介绍这一点,但这恰好适合我的需求,所以希望这对其他人有用。

如果您的代码等待输入逐个键入,那么我的答案应该没问题。如果你必须分析一个数据集,那么这是一个完全不同的工作。

请注意,这是一个幼稚的答案,不使用任何额外的库。 您还可以指定其他日期、时间和日期时间格式以满足您的要求。

from re import match
# Does not consider that 0 and 1 can be used to describe a BOOLEAN SQL value
# Use True, true and FALSE, false to describe SQL BOOLEAN values
PY_2_SQL_TYPE_PATTERNS = (
((r'^TRUE|true|FALSE|false$', ), 'BOOLEAN'),
((r'^d+$', ), 'INTEGER'),
((r'^d+.d+$', ), 'DOUBLE'),
((r'^d{4}/d{2}/d{2}$', ), 'DATE'),
((r'^d{2}:d{2}:d{2}.d{1,5}$', ), 'TIME'),
((r'^d{4}/d{2}/d{2} d{2}:d{2}:d{2}.d{1,5}$', ), 'DATETIME'),
((r'.*', ), 'VARCHAR'),  # Falls back to VARCHAR as .* will match anything
)

def get_sql_type(value):
'''
Find the corresponding SQL TYPE according to value
:param value: A value typed by the user
:return: The corresponding SQL TYPE from PY_2_SQL_TYPE_PATTERNS as a string
'''
for patterns, sql_type in PY_2_SQL_TYPE_PATTERNS:
for p in patterns:
if match(p, value):
return sql_type

v = input('Type a value: ').strip()
print(get_sql_type(v))

您可能需要对此进行测试,以确保没有需要考虑的特殊情况。

最新更新