{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# 动态编译" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 标准编程语言" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "对于 **C** 语言,代码一般要先编译,再执行。\n", "\n", " .c -> .exe" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 解释器语言" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "shell 脚本\n", "\n", " .sh -> interpreter" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Byte Code 编译" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "**Python, Java** 等语言先将代码编译为 byte code(不是机器码),然后再处理:\n", "\n", " .py -> .pyc -> interpreter" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## eval 函数" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " eval(statement, glob, local)\n", "\n", "使用 `eval` 函数动态执行代码,返回执行的值:" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "2" ] }, "execution_count": 1, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 1\n", "\n", "eval(\"a+1\")" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "可以接收明明空间参数:" ] }, { "cell_type": "code", "execution_count": 2, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 2, "metadata": {}, "output_type": "execute_result" } ], "source": [ "local = dict(a=2)\n", "glob = {}\n", "eval(\"a+1\", glob, local)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "这里 `local` 中的 `a` 先被找到。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## exec 函数" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " exec(statement, glob, local)\n", "\n", "使用 `exec` 可以添加修改原有的变量。" ] }, { "cell_type": "code", "execution_count": 3, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "2\n" ] } ], "source": [ "a = 1\n", "\n", "exec(\"b = a+1\")\n", "\n", "print b" ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "collapsed": false }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "{'a': 2, 'b': 3}\n" ] } ], "source": [ "local = dict(a=2)\n", "glob = {}\n", "exec(\"b = a+1\", glob, local)\n", "\n", "print local" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "执行之后,`b` 在 `local` 命名空间中。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## 警告" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "动态执行的时候要注意,不要执行不信任的用户输入,因为它们拥有 `Python` 的全部权限。" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## compile 函数生成 byte code" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ " compile(str, filename, mode)" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 5, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 1\n", "c = compile(\"a+2\", \"\", 'eval')\n", "\n", "eval(c)" ] }, { "cell_type": "code", "execution_count": 6, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "3" ] }, "execution_count": 6, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 1\n", "c = compile(\"b=a+2\", \"\", 'exec')\n", "\n", "exec(c)\n", "b" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## abstract syntax trees" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "collapsed": true }, "outputs": [], "source": [ "import ast" ] }, { "cell_type": "code", "execution_count": 8, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "\"Expression(body=BinOp(left=Name(id='a', ctx=Load()), op=Add(), right=Num(n=2)))\"" ] }, "execution_count": 8, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tree = ast.parse(\"a+2\", \"\", \"eval\")\n", "\n", "ast.dump(tree)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "改变常数的值:" ] }, { "cell_type": "code", "execution_count": 9, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "\"Expression(body=BinOp(left=Name(id='a', ctx=Load()), op=Add(), right=Num(n=3)))\"" ] }, "execution_count": 9, "metadata": {}, "output_type": "execute_result" } ], "source": [ "tree.body.right.n = 3\n", "\n", "ast.dump(tree)" ] }, { "cell_type": "code", "execution_count": 10, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "4" ] }, "execution_count": 10, "metadata": {}, "output_type": "execute_result" } ], "source": [ "a = 1\n", "c = compile(tree, '', 'eval')\n", "\n", "eval(c)" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "安全的使用方法 `literal_eval` ,只支持基本值的操作:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "collapsed": false }, "outputs": [ { "data": { "text/plain": [ "[10.0, 2, True, 'foo']" ] }, "execution_count": 11, "metadata": {}, "output_type": "execute_result" } ], "source": [ "ast.literal_eval(\"[10.0, 2, True, 'foo']\")" ] } ], "metadata": { "kernelspec": { "display_name": "Python 2", "language": "python", "name": "python2" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 2 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython2", "version": "2.7.10" } }, "nbformat": 4, "nbformat_minor": 0 }