#!/usr/bin/env python # coding: utf-8 # # 动态编译 # ## 标准编程语言 # 对于 **C** 语言,代码一般要先编译,再执行。 # # .c -> .exe # ## 解释器语言 # shell 脚本 # # .sh -> interpreter # ## Byte Code 编译 # **Python, Java** 等语言先将代码编译为 byte code(不是机器码),然后再处理: # # .py -> .pyc -> interpreter # ## eval 函数 # eval(statement, glob, local) # # 使用 `eval` 函数动态执行代码,返回执行的值: # In[1]: a = 1 eval("a+1") # 可以接收明明空间参数: # In[2]: local = dict(a=2) glob = {} eval("a+1", glob, local) # 这里 `local` 中的 `a` 先被找到。 # ## exec 函数 # exec(statement, glob, local) # # 使用 `exec` 可以添加修改原有的变量。 # In[3]: a = 1 exec("b = a+1") print b # In[4]: local = dict(a=2) glob = {} exec("b = a+1", glob, local) print local # 执行之后,`b` 在 `local` 命名空间中。 # ## 警告 # 动态执行的时候要注意,不要执行不信任的用户输入,因为它们拥有 `Python` 的全部权限。 # ## compile 函数生成 byte code # compile(str, filename, mode) # In[5]: a = 1 c = compile("a+2", "", 'eval') eval(c) # In[6]: a = 1 c = compile("b=a+2", "", 'exec') exec(c) b # ## abstract syntax trees # In[7]: import ast # In[8]: tree = ast.parse("a+2", "", "eval") ast.dump(tree) # 改变常数的值: # In[9]: tree.body.right.n = 3 ast.dump(tree) # In[10]: a = 1 c = compile(tree, '', 'eval') eval(c) # 安全的使用方法 `literal_eval` ,只支持基本值的操作: # In[11]: ast.literal_eval("[10.0, 2, True, 'foo']")