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

编辑:如果可能的话,我想避免使用 tryexcept。我想将它实现到一个异步的扭曲程序中,我认为 tryexcept 块所以它只会使程序同步。我是扭曲的新手,所以我不确定这是不是真的。


根据 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 的回答投赞成票。您需要引发异常。