python 中的智能类型转换
Smart type casting in python
我正在拨打 api 电话并在 json 收到回复
result = {'foo': '123.456', 'bar': '23', 'donald': 'trump', 'time': '2016-04-07T05:31:49.532124Z'}
尽管结果是字典或列表,但内容始终是字符串。我想将这些值转换为适当的类型。 (即 '123.456'
为浮点数,'23'
为整数,'time'
为日期时间。)
我的代码有效,但似乎应该有一种 simpler/more 有效的方法来做到这一点。在那儿?
这是我的版本
from dateutil.parser import parse
def is_float(x):
try:
float(x)
return True
except ValueError:
return False
def is_int(x):
try:
a = float(x)
b = int(a)
except ValueError:
return False
else:
return a == b
def is_datetime(x):
try:
parse(x)
return True
except ValueError:
return False
def smartcast(x):
if isinstance(x, dict):
return { k:smartcast(v) for k, v in x.items() }
elif isinstance(x, list):
return map(smartcast, x)
elif is_int(x):
return int(x)
elif is_float(x):
return float(x)
elif is_datetime(x):
return parse(x)
else:
return x
编辑:如果可能的话,我想避免使用 try
和 except
。我想将它实现到一个异步的扭曲程序中,我认为 try
和 except
块所以它只会使程序同步。我是扭曲的新手,所以我不确定这是不是真的。
根据 Francesco 的解决方案,这是更新后的代码。
from dateutil.parser import parse
def smartcast(x):
if isinstance(x, dict):
return { k:smartcast(v) for k, v in x.items() }
elif isinstance(x, list):
return map(smartcast, x)
else:
for t in [int, float, parse]:
try:
return t(x)
except ValueError:
continue
return x
什么是合适的类型?我问这个是为了强调有时对于人类来说也不清楚类型是什么:你确定 "42"42" 总是一个 int 或者有时它必须被认为是字符串?
无论如何,就像您所做的那样,您可以使用在您的上下文中有意义的规则构建解决方案。
对于您的情况,您可以使用一个简单的循环来简化代码
from dateutil.parser import parse
tests = [int, float, parse]
def smartcast(value):
for test in tests:
try:
return test(value)
except ValueError:
continue
# No match
return value
使用 ast.literal_eval() 怎么样?
https://docs.python.org/2/library/ast.html#ast.literal_eval
对 Francesco 的回答投赞成票。您需要引发异常。
我正在拨打 api 电话并在 json 收到回复
result = {'foo': '123.456', 'bar': '23', 'donald': 'trump', 'time': '2016-04-07T05:31:49.532124Z'}
尽管结果是字典或列表,但内容始终是字符串。我想将这些值转换为适当的类型。 (即 '123.456'
为浮点数,'23'
为整数,'time'
为日期时间。)
我的代码有效,但似乎应该有一种 simpler/more 有效的方法来做到这一点。在那儿?
这是我的版本
from dateutil.parser import parse
def is_float(x):
try:
float(x)
return True
except ValueError:
return False
def is_int(x):
try:
a = float(x)
b = int(a)
except ValueError:
return False
else:
return a == b
def is_datetime(x):
try:
parse(x)
return True
except ValueError:
return False
def smartcast(x):
if isinstance(x, dict):
return { k:smartcast(v) for k, v in x.items() }
elif isinstance(x, list):
return map(smartcast, x)
elif is_int(x):
return int(x)
elif is_float(x):
return float(x)
elif is_datetime(x):
return parse(x)
else:
return x
编辑:如果可能的话,我想避免使用 try
和 except
。我想将它实现到一个异步的扭曲程序中,我认为 try
和 except
块所以它只会使程序同步。我是扭曲的新手,所以我不确定这是不是真的。
根据 Francesco 的解决方案,这是更新后的代码。
from dateutil.parser import parse
def smartcast(x):
if isinstance(x, dict):
return { k:smartcast(v) for k, v in x.items() }
elif isinstance(x, list):
return map(smartcast, x)
else:
for t in [int, float, parse]:
try:
return t(x)
except ValueError:
continue
return x
什么是合适的类型?我问这个是为了强调有时对于人类来说也不清楚类型是什么:你确定 "42"42" 总是一个 int 或者有时它必须被认为是字符串?
无论如何,就像您所做的那样,您可以使用在您的上下文中有意义的规则构建解决方案。
对于您的情况,您可以使用一个简单的循环来简化代码
from dateutil.parser import parse
tests = [int, float, parse]
def smartcast(value):
for test in tests:
try:
return test(value)
except ValueError:
continue
# No match
return value
使用 ast.literal_eval() 怎么样?
https://docs.python.org/2/library/ast.html#ast.literal_eval
对 Francesco 的回答投赞成票。您需要引发异常。