[ ]
宙飒天下网 1. 动态编译
动态编译指的是在运行时接收字符串,动态的将其编译为python可执行的代码的功能.
python提供了两个函数用于实现动态编译:
exec和eval函数
eval(exp[, globals[, locals]])globals是字典形式,表示全局命名空间,如果传入globals的字典中缺少__builtins__的时候,当前的全局命名空间将作为globals参数输入并在表达式计算之前被解析.locals则为任何映射对象,表示局部命名空间,与globals两者默认相同.如果两者都省略则表示在eval的调用环境中执行
exec()与
eval()类似的是exec()方法,但exec是翻译并执行.exec常与文件读取操作结合使用,直接传递python的代码文件运行
a = eval("lambda *x: sum(x)") a(1,2,3,4,5) 15 %timeit a(1,2,3,4,5,6,7,8,9) 258 ns ± 2.81 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each) %timeit lambda *x:sum(x)(1,2,3,4,5,6,7,8,9) 58 ns ± 0.763 ns per loop (mean ± std. dev. of 7 runs, 10000000 loops each) exec("aa = lambda x: x") aa(10) 10 eval和exec有两个弊端:
降低运算效率
如上面看到的,运行时间上差距不小
安全性
这主要是因为可以调用一些危险的方法而没有设限.也就是所谓的代码注入攻击.
当然了,我们也可以通过限制globals和locals来实现对可用项的限制.
如果只是为了传入参数,那么可以使用ast库的literal_eval函数,它是安全的
a(1,2,3,4,5) 0 a(1,2,3,4,5) 1 a(1,2,3,4,5) 2在Python中做元编程时,最好不用exec 和eval 函数.如果接收的字符串(或片段)来自不可信的源,那么这两个函数会带来严重的安全风险.Python提供了充足的内省工具,大多数时候都不需要使用exec和eval函数.然而,Python核心开发者实现namedtuple函数时选择了使用exec函数,这样做是为了让生成的类代码能通过._source获取.




还没有评论,来说两句吧...