通过 Python 的 eval() 运行 JSON?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1083250/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Running JSON through Python's eval()?
提问by Ben Blank
Best practices aside, is there a compelling reason notto do this?
撇开最佳实践不谈,是否有令人信服的理由不这样做?
I'm writing a post-commit hook for use with a Google Code project, which provides commit data via a JSON object. GC provides an HMAC authentication token along with the request (outside the JSON data), so by validating that token I gain high confidence that the JSON data is both benign (as there's little point in distrusting Google) and valid.
我正在编写一个用于 Google Code 项目的提交后挂钩,该项目通过 JSON 对象提供提交数据。GC 提供 HMAC 身份验证令牌以及请求(在 JSON 数据之外),因此通过验证该令牌,我非常确信 JSON 数据是良性的(因为不信任 Google 没什么意义)和有效。
My own (brief) investigations suggest that JSON happens to be completely valid Python, with the exception of the "\/"
escape sequence — which GC doesn't appear to generate.
我自己的(简要)调查表明 JSON 恰好是完全有效的 Python,除了"\/"
转义序列 - GC 似乎没有生成。
So, as I'm working with Python 2.4 (i.e. no json
module), eval()
is looking reallytempting.
所以,当我使用 Python 2.4(即没有json
模块)时,eval()
看起来真的很诱人。
Edit:For the record, I am very much notasking if this is a good idea. I'm quiteaware that it isn't, and I very much doubt I'll ever use this technique for any future projects even if I end up using it for this one. I just wanted to make sure that I know what kind of trouble I'll run into if I do. :-)
编辑:为了记录,我不是在问这是否是一个好主意。我很清楚它不是,我非常怀疑我是否会在未来的任何项目中使用这种技术,即使我最终将它用于这个项目。我只是想确保我知道如果我这样做会遇到什么样的麻烦。:-)
回答by Kiv
If you're comfortable with your script working fine for a while, and then randomly failing on some obscure edge case, I would go with eval.
如果您对脚本可以正常工作一段时间感到满意,然后在某些模糊的边缘情况下随机失败,我会选择 eval。
If it's important that your code be robust, I would take the time to add simplejson. You don't need the C portion for speedups, so it really shouldn't be hard to dump a few .py files into a directory somewhere.
如果您的代码健壮很重要,我会花时间添加 simplejson。您不需要 C 部分进行加速,因此将一些 .py 文件转储到某个目录中确实不难。
As an example of something that might bite you, JSON uses Unicode and simplejson returns Unicode, whereas eval returns str:
举个可能会咬你的例子,JSON 使用 Unicode,simplejson 返回 Unicode,而 eval 返回 str:
>>> simplejson.loads('{"a":1, "b":2}')
{u'a': 1, u'b': 2}
>>> eval('{"a":1, "b":2}')
{'a': 1, 'b': 2}
Edit: a better example of where eval() behaves differently:
编辑:一个更好的例子,说明 eval() 的行为不同:
>>> simplejson.loads('{"X": "\uabcd"}')
{u'X': u'\uabcd'}
>>> eval('{"X": "\uabcd"}')
{'X': '\uabcd'}
>>> simplejson.loads('{"X": "\uabcd"}') == eval('{"X": "\uabcd"}')
False
Edit 2: saw yet another problem today pointed out by SilentGhost: eval doesn't handle true -> True, false -> False, null -> None correctly.
编辑 2:今天又看到 SilentGhost 指出的另一个问题:eval 不能正确处理 true -> True, false -> False, null -> None。
>>> simplejson.loads('[false, true, null]')
[False, True, None]
>>> eval('[false, true, null]')
Traceback (most recent call last):
File "<interactive input>", line 1, in <module>
File "<string>", line 1, in <module>
NameError: name 'false' is not defined
>>>
回答by James Thompson
The point of best practices is that in most cases, it's a bad idea to disregard them. If I were you, I'd use a parser to parse JSON into Python. Try out simplejson, it was very straightforward for parsing JSON when I last tried it and it claims to be compatible with Python 2.4.
最佳实践的要点是,在大多数情况下,忽视它们是一个坏主意。如果我是你,我会使用解析器将 JSON 解析为 Python。试试simplejson,当我上次尝试它时解析 JSON 非常简单,它声称与 Python 2.4 兼容。
I disagree that there's little point in distrusting Google. I wouldn't distrust them, but I'd verify the data you get from them. The reason that I'd actually use a JSON parser is right in your question:
我不同意不信任谷歌毫无意义。我不会不信任他们,但我会验证您从他们那里获得的数据。我实际使用 JSON 解析器的原因在您的问题中是正确的:
My own (brief) investigations suggest that JSON happens to be completely valid Python, with the exception of the "/" escape sequence — which GC doesn't appear to generate.
我自己的(简要)调查表明 JSON 恰好是完全有效的 Python,除了“/”转义序列 - GC 似乎不会生成。
What makes you think that Google Code will never generate an escape sequence like that?
是什么让您认为 Google Code 永远不会生成这样的转义序列?
Parsing is a solved problem if you use the right tools. If you try to take shortcuts like this, you'll eventually get bitten by incorrect assumptions, or you'll do something like trying to hack together a parser with regex's and boolean logic when a parser already exists for your language of choice.
如果您使用正确的工具,解析是一个已解决的问题。如果您尝试像这样走捷径,您最终会被错误的假设所困扰,或者当您选择的语言已经存在解析器时,您会尝试将解析器与正则表达式和布尔逻辑组合在一起。
回答by eradman
One major difference is that a boolean in JSON is true
|false
, but Python uses True
|False
.
一个主要区别是 JSON 中的布尔值是true
| false
,但 Python 使用True
| False
.
The most important reason not to do this can be generalized: eval
should never be used to interpret external input since this allows for arbitrary code execution.
不这样做的最重要的原因可以概括为:eval
永远不要用于解释外部输入,因为这允许任意代码执行。
回答by Jason Baker
eval
ing JSON is a bit like trying to run XML through a C++ compiler.
eval
使用 JSON 有点像尝试通过 C++ 编译器运行 XML。
eval
is meant to evaluate Python code. Although there are some syntactical similarities, JSON isn't Python code. Heck, not only is it not Pythoncode, it's not code to begin with. Therefore, even if you can get away with it for your use-case, I'd argue that it's a bad idea conceptually. Python is an apple, JSON is orange-flavored soda.
eval
旨在评估 Python 代码。尽管存在一些语法相似之处,但JSON 不是 Python 代码。哎呀,它不仅不是Python代码,也不是一开始的代码。因此,即使您可以在用例中侥幸成功,我认为从概念上讲这是个坏主意。Python 是苹果,JSON 是橙味苏打水。