我一直在尝试转换一串字典对象,如下所示
"{'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库是为了解决这样的问题而构建的吗?除此之外还有什么好方法可以解决问题吗?
答案 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
。它只是留下了一个巨大的安全漏洞,只是为了边际效益。