eval+exec+compile

来源:互联网 发布:怎么通过淘宝客赚钱 编辑:程序博客网 时间:2024/05/17 22:45

eval, exec, compile
根据给的字符串编译成字节码,然后再执行代码

eval(str[,globals[,locals]]):eval函数一般接收的字符串是表达式,都是会有返回结果的。参数globals是它执行的全局环境,locals是它的局部环境。
如果不赋值的话,就把当前的全局变量和局部变量作为它的值。
>>> eval("print 2")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<string>", line 1
    print 2
        ^
SyntaxError: invalid syntax
>>> eval("3+4*5")
23
>>>


从上面的测试代码来看,它一般不会接收语句的执行的。

exec(str[,globals[,locals]]):exec语句参数的含义大体与eval相同。但是它可以接收一组语句的字符串。

>>> exec("print 2")
2
>>> exec("3*4")
>>> exec("for i in range(0,5): print i")
0
1
2
3
4
>>>

compile(str, filename, kind):compile函数将字符串编译为字节码。其中的str是包含要编译的字符串。
而filename是定义的该字符串的文件(在跟踪生成中使用)。kind参数指定了要编译代码的类型(single:一条语句,exec:一组语句,eval:一个表达式)
还可以将compile()函数返回的代码对象传递给eval函数和exec语句。


>>> s="for i in range(0,10): print i"
>>> c=compile(s,'','exec')
>>> exec(c)
0
1
2
3
4
5
6
7
8
9
>>> s2="3*7+6"
>>> c2=compile(s2,'','eval')
>>> eval(c2)
27
>>> s3="print 2"
>>> c3 = compile(s3,'','single')
>>> print c3
<code object <module> at 0x34039890, file "", line 1>
>>> eval(cs)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'cs' is not defined
>>> eval(c3)
2
>>> exec(c3)
2
>>> eval(c)
0
1
2
3
4
5
6
7
8
9
>>>



>>> def test():
...     print 5
...
>>> eval("test()")
5
>>> exec("test()")
5
>>> def test1():
...     return 5
...
>>> exec("test1()")
>>> a=exec("test1()")
  File "<stdin>", line 1
    a=exec("test1()")
         ^
SyntaxError: invalid syntax
>>> print exec("test1()")
  File "<stdin>", line 1
    print exec("test1()")
             ^
SyntaxError: invalid syntax
>>> a=eval("test1()")
>>> print a
5
>>> print eval("test1()")
5
>>>

 

 

下面是一个带参数的函数调用的例子(非常重要哦):

>>> import datetime
>>> def test(a,b):
...     print a,b
...    

>>> eval("test")(datetime.date.today(),datetime.date.today()-datetime.timedelta(days=1))
2011-02-28 2011-02-27

>>> exec("test(datetime.date.today(),datetime.date.today()-datetime.timedelta(days=1))")
2011-02-28 2011-02-27

>>> c=compile("test", '', 'eval')
>>> eval(c)(datetime.date.today(),datetime.date.today()-datetime.timedelta(days=1))
2011-02-28 2011-02-27

>>> c1=compile("test(datetime.date.today(),datetime.date.today()-datetime.timedelta(days=1))", '', 'exec')
>>> exec(c1)
2011-02-28 2011-02-27

>>> c2=compile("test", '', 'exec')
>>> exec(c2)(datetime.date.today(),datetime.date.today()-datetime.timedelta(days=1))
Traceback (most recent call last):
  File "<input>", line 1, in <module>
TypeError: 'code' object is not callable

>>> c3=compile("test(datetime.date.today(),datetime.date.today()-datetime.timedelta(days=1))",'','single')
>>> eval(c3)
2011-02-28 2011-02-27
>>> eval("test(datetime.date.today(),datetime.date.today()-datetime.timedelta(days=1))")
2011-02-28 2011-02-27

 

 

由上述的例子可知,编译后的字节码在eval函数exec语句中都可以执行的。此时eval函数和exec语句基本上是没什么区别的。
也说明了eval函数和exec语句只是在编译字符串为字节码上面是有区别的,执行字节码可能是调用的同样的函数或操作。

原创粉丝点击