@@ -155,4 +155,99 @@ print astor.to_source(module)
155
155
156
156
```
157
157
158
- 有一个好消息是 3.9 开始支持 ` ast.unparse ` 反解析函数。
158
+ 有一个好消息是 Python 3.9 开始支持 ` ast.unparse ` 反解析函数。
159
+
160
+ ### 安全的执行
161
+
162
+ 在 Python 中有 ` eval ` 方法,但是一般如果直接调用 ` eval ` 执行的话,会有安全风险,可以试下 ` ast.literal_eval ` 进行安全的代码执行。
163
+
164
+ 这个代码执行可以厉害了` ୧(๑•̀◡•́๑)૭ ` , 只能含有 Python 基本数据类型,数字,字符串,列表,字典,元组,布尔值,` None ` 和复数。
165
+ > 😂,复数?是不是突然觉得很突然,为什么会有复数?你是不是已经把复数是啥给忘了?` 1+2j ` 就是复数。
166
+
167
+ ``` python
168
+ def literal_eval (node_or_string ):
169
+ """
170
+ Safely evaluate an expression node or a string containing a Python
171
+ expression. The string or node provided may only consist of the following
172
+ Python literal structures: strings, numbers, tuples, lists, dicts, booleans,
173
+ and None.
174
+ """
175
+ _safe_names = {' None' : None , ' True' : True , ' False' : False }
176
+ if isinstance (node_or_string, basestring ):
177
+ node_or_string = parse(node_or_string, mode = ' eval' )
178
+ if isinstance (node_or_string, Expression):
179
+ node_or_string = node_or_string.body
180
+ def _convert (node ):
181
+ if isinstance (node, Str):
182
+ return node.s
183
+ elif isinstance (node, Num):
184
+ return node.n
185
+ elif isinstance (node, Tuple):
186
+ return tuple (map (_convert, node.elts))
187
+ elif isinstance (node, List):
188
+ return list (map (_convert, node.elts))
189
+ elif isinstance (node, Dict):
190
+ return dict ((_convert(k), _convert(v)) for k, v
191
+ in zip (node.keys, node.values))
192
+ elif isinstance (node, Name):
193
+ if node.id in _safe_names:
194
+ return _safe_names[node.id]
195
+ elif isinstance (node, BinOp) and \
196
+ isinstance (node.op, (Add, Sub)) and \
197
+ isinstance (node.right, Num) and \
198
+ isinstance (node.right.n, complex ) and \
199
+ isinstance (node.left, Num) and \
200
+ isinstance (node.left.n, (int , long , float )):
201
+ left = node.left.n
202
+ right = node.right.n
203
+ if isinstance (node.op, Add):
204
+ return left + right
205
+ else :
206
+ return left - right
207
+ raise ValueError (' malformed string' )
208
+ return _convert(node_or_string)
209
+ ```
210
+
211
+ 源码很简单,可以直接看代码,或者手动测试。
212
+
213
+ 赋值操作不能用,加减乘除不能用,比较运算不能用,连集合都不能用。复数可以用,负数也可以,但是正数就不行。
214
+ > 好消息是从 Python 3.2 开始支持集合。
215
+
216
+ ``` python
217
+ # -*- coding: utf-8 -*-
218
+
219
+ import ast
220
+
221
+
222
+ if __name__ == ' __main__' :
223
+ # 赋值操作不能有
224
+ # print ast.literal_eval("a=1")
225
+ # print eval("a=1")
226
+ # a = 1
227
+ # 加减乘除都不能有
228
+ # print ast.literal_eval("1+1")
229
+ # print eval("1+1")
230
+ # print ast.literal_eval("1==1")
231
+ print eval (" 1==1" )
232
+ print ast.literal_eval(" 1" )
233
+ print ast.literal_eval(" None" )
234
+ # 连集合都不能有
235
+ # print ast.literal_eval("{1,2,4}")
236
+ # print ast.literal_eval("set([1])")
237
+ # print ast.literal_eval("[1,2,{'1', 2, '2,3,4'}, [4,5,'6']]")
238
+ # print [1,2,{'1', 2, '2,3,4'}, [4,5,'6']]
239
+ print ast.literal_eval(" [1,2,3,{2:3 } ]" )
240
+ # 连最终结果是一个list也不行
241
+ # print ast.literal_eval("list([1,2,3])")
242
+ print list ([1 , 2 , 3 ])
243
+ # print ast.literal_eval("[1,2+3]")
244
+ # 复数可以有,负数也可以有
245
+ print ast.literal_eval(" 1+2j" )
246
+ print ast.literal_eval(" -2" )
247
+ # print ast.literal_eval("--2")
248
+ # 正数就不行
249
+ # print ast.literal_eval("+2")
250
+ # print ast.literal_eval("++2")
251
+
252
+ ```
253
+
0 commit comments