eval(X, type("_Dummy", (dict,), {'__getitem__': lambda name, value: name}))
这段代码最重要的一个应用是可以格式化非标准的JSON数据,比如
X = { key: "value" } eval(X, type("", (dict,), {'__getitem__': lambda s, n: n})())
这样可以转化成标准字典
那么这一句神奇的东西该怎么解释呢?
首先type在这里充当的不是返回类型的作用,这里作为一个class constructor的存在,第一个参数是类名,第二个参数为类的基类,第三个参数为一个字典,表示这个类的成员和方法。
那么,eval(X, type("", (dict,), {'__getitem__': lambda s, n: n})())
就是创建了一个临时的 _Dummy
类,上面的语句规约为
eval(X, _Dummy)
那么eval的第二个的参数什么意思呢?
>>> help(eval) eval(...) eval(source[, globals[, locals]]) -> value Evaluate the source in the context of globals and locals. The source may be a string representing a Python expression or a code object as returned by compile(). The globals must be a dictionary and locals can be any mapping, defaulting to the current globals and locals. If only globals is given, locals defaults to it.
我们就知道了,这个求X的值里涉及到的变量 key 这个变量会放到 _Dummy()
里去求,则会等价于调用 _Dummy()['key']
,此时就会调用到我们的 __getitem__
,这个方法我们定义了返回 name 也就是 “key” ,所以,一个变量名在这里就转换成了字符串。
但是eval毕竟是eval,在使用它的时候永远不要相信用户输入的参数,无论哪个语言的eval,滥用的结果都是惨重的。比如说:
福尔摩喵
(大喵神) 给出了一个 Referencence,写出了如何构造有害的东西来搞事情。
这里有篇文章涉及 Python 解释器安全 Paving the Way to Securing the Python Interpreter
还有个Pypy的sandbox Pypy feature#sandboxing
感谢博主!解释了我的困惑!
LikeLike