将python ast库用于将字符串转换为dict等操作是一种最佳实践

时间:2015-10-06 10:18:15

标签: python json type-conversion

我一直在尝试转换一串字典对象,如下所示

"{'Cmd': None, 'Hostname': None, 'Entrypoint': None, 'Env': None,     'OpenStdin': False, 
'Tty': False, 'Domainname': None, 'Image': u'nginx:latest', 'HostConfig':   
{'Binds': None, 'RestartPolicy': {}, 'NetworkMode': u'bridge', 'Dns': None, 
'Links': [], 'PortBindings': {}, 'DnsSearch': None, 'Privileged': False,
'VolumesFrom': []}, 'ExposedPorts': {}, 'User': None}"

到python字典。

但解决方案出现时,搜索建议使用python ast库达到此目的。如

import ast
ast.literal_eval(string)

它工作正常。但是,ast库是为了解决这样的问题而构建的吗?除此之外还有什么好方法可以解决问题吗?

1 个答案:

答案 0 :(得分:2)

  

但是ast库是为了解决这样的问题而构建的吗?

您的担忧是有效的。正如ast.literal_eval一样,eval并非主要用于反序列化数据。那是因为 Python代码从未被设计为首先序列化数据

但是它并没有什么异国情调:在引擎盖下,它使用了解释器的内置compile()(这与CPython用于解析普通代码的功能相同),但是literal_eval还会生成并通过AST,如果它包含除文字之外的任何内容,则会引发异常。

在实践中,您需要考虑两个问题:安全性和安全性。性能。对于您发布的示例,性能不应该是一个问题,因此您应该坚持ast.literal_eval(到目前为止thought是非常安全的)。但是,如果您正在处理(更多)更大的词典,那么您可能会遇到一些内存问题。

在这种情况下,如果可能的话,到目前为止更合理的选择是避免首先将数据序列化为Python代码并使用类似JSON的东西。如果没有,请考虑在解析之前将字符串转换为其他形式;例如,您可以使用正则表达式将其转换为JSON(格式非常相似),然后使用json.loads进行解析。但只要你没有遇到性能问题,坚持ast.literal_eval就可以了。你应该没事。

无论如何,无论你做什么,永远不要永远使用eval。它只是留下了一个巨大的安全漏洞,只是为了边际效益。