python中的智能类型转换

时间:2016-04-07 05:44:41

标签: python types casting twisted

我正在进行api调用并在json中收到回复,如此

result = {'foo': '123.456', 'bar': '23', 'donald': 'trump', 'time': '2016-04-07T05:31:49.532124Z'}

虽然结果是字典或列表,但内容始终是字符串。我想将这些值转换为适当的类型。 (即'123.456'到浮点数,'23'到int,'time'到日期时间。)

我的代码有效,但似乎应该有更简单/更有效的方法来执行此操作。在那儿?

这是我的版本

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

2 个答案:

答案 0 :(得分:3)

什么是合适的类型?我要求这一点强调有时候对于人类来说还不清楚类型是什么:你确定“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

答案 1 :(得分:0)

使用ast.literal_eval()怎么样?

https://docs.python.org/2/library/ast.html#ast.literal_eval

投票支持弗朗西斯科的回答。你需要提出异常。