当literal_eval失败时:使用星号表示法读取日期时间对象

python中的一项重要功能是 AST  (抽象语法树) 图书馆’s 文字评估 。这使您可以读取python数据类型的字符串版本:

1
2
3
4
5
6
7
8
9
>>> AST 进口 文字评估
>>> #带有一些琐碎信息的示例字典
>>> myDict = “ {'someKey':1,'otherother':2}”
>>> #让我们使用函数进行解析
>>> testEval = 文字评估(myDict)
>>> 打印 testEval
{'someKey': 1, “ otherKey”: 2}
>>> 类型(testEval)
<类型 'dict'>

像这样导入字典类似于 解析JSON 使用Python’s  json.负载 解码器。但是它也有缺点’s 的 JSON’s的限制性数据类型,如我们在字典中包含例如datetime对象时所见:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
>>> myDict = “ {'someKey':1,'rightNow':datetime.datetime(2013,8,10,21,46,52,638649)}“
>>>
>>> 文字评估(myDict)
追溯 (最近 呼叫 持续):
  文件 "<stdin>", 线 1, <模组 >
  文件 “ /root/anaconda/lib/python2.7/ast.py”, 线 80, 文字评估
    返回 _兑换(节点_or_string)
  文件 “ /root/anaconda/lib/python2.7/ast.py”, 线 63, _兑换
     压缩(节点., 节点.价值观))
  文件 “ /root/anaconda/lib/python2.7/ast.py”, 线 62, <基因>
    返回 字典((_兑换(k), _兑换(v)) 对于 k, v
  文件 “ /root/anaconda/lib/python2.7/ast.py”, 线 79, _兑换
    提高 ValueError(“格式错误的字符串”)
ValueError: 畸形的

因此,您可以尝试编写一些代码来自己解析字典数据类型。这变得非常棘手,但是最终您可能可以容纳所有常见的数据类型:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
定义 read_dict(d):
    “接受包含字典的字符串。
    试图对此进行解析并返回字典。”
    parsed_dict = {} #结果
    #删除{}并分成大块
    d = d[1:-1].分裂(',')
    #遍历大块并尝试解释它们
    对于 kv_pair d:
        #由中央结肠分裂
        kv_pair = kv_pair.分裂(“:”)
        #解释键和值
        k = 我是什么(kv_pair[0])
        v = 我是什么(kv_pair[1])
        #添加到最终解析的字典中
        parsed_dict[k] = v
    返回 parsed_dict
 
定义 我是什么(事情):
    “解释字符串的简单尝试
    数据类型。可以处理字符串和整数”
    #删除任何反引号
    如果 事情.以。。开始(“”) 要么 事情.以。。开始(“”):
        事情 = 事情[1:-1]
 
    #Now检查数据类型(尽管还有更多方法)
    如果 事情.等轴():
        返回 整型(事情) #返回数字
    其他:
        返回 事情 #返回字符串
    #如果任何一个都无法识别,则返回错误
    返回 “数据损坏”

但这仍然没有’真正解决我们的日期时间对象问题:

1
2
3
4
5
>>> read_dict(myDict)
追溯 (最近 呼叫 持续):
  文件 "<stdin>", 线 1, <模组 >
  文件 "<stdin>", 线 13, read_dict
IndexError: 清单 指数 范围

这是本文重点所在。起初我以为我可以处理日期时间’通过提取类进行格式化  约会时间.约会时间(2013, 8, 10, 21, 46, 52, 638649) 作为一个元组,方法是将其放在括号中,然后将其返回日期时间,例如: 

1
2
3
4
5
>>> x = (2013, 8, 10, 21, 46, 52, 638649)
>>> parsedDate = 约会时间(x)
追溯 (最近 呼叫 持续):
  文件 "<stdin>", 线 1, <模组 >
TypeError: 一个 整数 需要

但显然不是。必须提取元组–不是通过lambda或列表理解,而是实际上使用星号表示法:

1
2
3
>>> parsedDate = 约会时间(*x)
>>> 打印 parsedDate
2013-08-10 21:46:52.638649

星号(*)将x等可迭代程序解压缩为该函数的位置参数。简单!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
定义 我是什么(事情):
    “解释字符串的简单尝试
    数据类型。可以处理str,int,datetime”
    #删除任何反引号
    如果 事情.以。。开始(“”) 要么 事情.以。。开始(“”):
        事情 = 事情[1:-1]
 
    #现在检查某些数据类型
    如果 事情.等轴():
        返回 整型(事情) #返回数字
    小精灵 事情.以。。开始('约会时间'):
        #获取括号之间的数字
        事情 = 事情.分裂('(')[1].分裂(')')[0]
        #解析数字,解压缩为日期时间并返回
        返回 约会时间(*[整型(x) 对于 x 事情])
    其他:
        返回 事情 #返回字符串
    #如果任何一个都无法识别,则返回错误
    返回 “数据损坏”

发表评论