当前位置:主页 > python教程 > Python中字符串类型代码的执行函数

Python中字符串类型代码的执行函数——eval()、exec()和compile()详解

发布:2023-04-17 10:35:02 59


给网友朋友们带来一篇相关的编程文章,网友农莺莺根据主题投稿了本篇教程内容,涉及到Python中字符串类型代码的执行函数、Python、eval()、exec()和compile()、Python中字符串类型代码的执行函数相关内容,已被957网友关注,相关难点技巧可以阅读下方的电子资料。

Python中字符串类型代码的执行函数

字符串类型代码的执行

字符串类型代码的执行函数有三个,都是Python的内置函数。

  • eval()执行字符串类型的代码,并返回最终结果。
  • exec()执行字符串类型的代码。
  • compile()将字符串类型的代码编码。代码对象能够通过exec语句来执行或者eval()进行求值。

下面来一一介绍这三个函数。

eval()

执行一个字符串表达式,并返回表达式的值

eval(expression[, globals[, locals]])

参数

  • expression:Python 表达式。
  • globals:必须是一个字典对象,否则程序会出错。当定义了globals参数之后eval函数的作用域会被限定在globals中。
  • locals:该参数掌控局部的命名空间,功能和globals类型,不过当参数冲突时,会执行locals处的参数。

例子一:因为此处没有指定globals和locals,所以直接执行expression部分的内容。

>>> a = 10
>>> eval("a ** 3")
1000

例子二:globals参数示例。

>>> a = 10
>>> g = {'a': 5}
>>> eval("a + 1", g)
6

因为现在指定了globals,所以在expression部分的作用域就是globals指定的字典范围内。所以此时外面的a=10被屏蔽,取用字典中的值。

例子三:locals参数示例

>>> a = 10
>>> b = 15
>>> c = 20
>>> g = {"a": 6, "b": 8}
>>> t = {"b": 1000, "c": 10}
>>> eval("a + b + c", g, t)
1016

上面提到了,当有globals和locals时作用的范围域是在globals和locals中,所以a=1,b=20,c=30不会被应用。a和c的值分别去字典g和字典t中的值,当globals和locals中都有参数b时取locals中的值。所以a=6,b=100,c=10。

exec()

在Python中,exec()是一个十分有趣且实用的内置函数,不同于eval()函数只能执行计算数学表达式的结果的功能,exec()能够动态地执行复杂的Python代码,能够十分强大。参数如下:

  • object:必选参数,必须是字符串或 code 对象。如果 object 是一个字符串,该字符串会先被解析为一组 Python 语句,然后在执行(除非发生语法错误)。如果 object 是一个 code 对象,那么它只是被简单的执行。
  • globals:可选参数,表示全局命名空间(存放全局变量)必须是一个字典对象。
  • locals:可选参数,表示当前局部命名空间(存放局部变量)可以是任何映射对象。如果该参数被忽略,那么它将会取与 globals 相同的值。

下面来看一些例子。

例子一:执行简单的代码

>>> a = 12
>>> b = 30
>>> exec("ans = a * b")
>>> ans
360

例子二:func为字符串,它是一个递归地计算整数阶乘的函数。因为exec()仅支持string和code object参数,所以我们要将该递归函数转化成一个字符串,当然,格式还是要Python代码的格式来,注意换行和缩进。刚才例子的输出结果为:

>>> func = "def fact(n):\n\treturn 1 if n == 1 else n * fact(n - 1)
>>> exec(func)
>>> a = fact(5)
>>> a
120

例子三:exec()的参数和上面的eval()一模一样。

>>> x = 15
>>> expr = "z = 30\nsum = x + y + z\nprint(sum)"
>>> y = 20
>>> exec(expr)
65
>>> exec(expr, {'x': 1, 'y': 2})
33
>>> exec(expr, {'x': 1, 'y': 2}, {'y': 100, 'z': 4})
131

例子四:说到这里,可能有些疑问了?事实上,这些代码不是直接能够在Python中执行吗,为何还要多此一举?在实际项目中,我们有些时候会将Python代码写入一些文件中,举个例子,如以下的eg.txt,它储存了我们想要的Python代码,如下:

def fact(n):
    if n == 1:
        return 1
    else:
        return n * fact(n - 1)
        
t = fact(6)
print(t)

请再次注意,这是一个txt格式的Python代码。那么,我们如何调用它呢?答案就是exec()函数,代码如下:

with open('E://eg.txt', 'r') as f:
    s = f.read()
 
exec(s)

compile()

compile()函数将一个字符串编译为字节代码或 AST 对象。代码对象可以被 exec()或 eval() 执行。以下是compile()方法的语法:

compile(source, filename, mode[, flags[, dont_inherit]])

参数如下:

  • source :可以是常规的字符串、字节字符串,或者 AST 对象
  • filename:代码文件名称,如果不是从文件读取代码则传递一些可辨认的值。
  • mode:指定编译代码的种类。可以指定为 exec, eval, single。
  • 如果是exec类型,表示这是一个序列语句,可以进行运行;
  • 如果是eval类型,表示这是一个单一的表达式语句,可以用来计算相应的值出来;编译代码时,如果语法出错会返回SyntaxError;如果代码包含一些空字节,则返回类型错误TypeError。
  • 如果是single类型,表示这是一个单一语句,采用交互模式执行,在这种情况下,如果是一个表达式,一般会输出结果,而不是打印为None输出。
  • flags:变量作用域,局部命名空间,如果被提供,可以是任何映射对象。
  • flags和dont_inherit是用来控制编译源码时的标志。

编译代码时,如果语法出错会返回SyntaxError;如果代码包含一些空字节,则返回类型错误TypeError。

注意事项:当采用single或eval类型编译时,如果有多行代码,每行代码后面至少有一个换行符,否则在code模块编译时就会提示编译的源码不完整错误。在Python 3.2版本之后,允许输入Windows或Mac的换行符;当采用exec模式时,不需要在每个行后面输入换行符;在这个版本之后增加了优化参数。

例子:

>>> str = "for i in range(0,10): print(i)"
>>> c = compile(str, '', 'exec')
>>> exec(c)  # eval 也可以
0
1
2
3
4
5
6
7
8
9
>>> str = "3 * 4 + 5"
>>> a = compile(str, '', 'eval')
>>> eval(a)
17

到此这篇关于Python中字符串类型代码的执行函数——eval()、exec()和compile()的文章就介绍到这了,更多相关Python中字符串类型代码的执行函数内容请搜索码农之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持码农之家!


参考资料

相关文章

  • Python3中函数参数传递方式浅析

    发布:2019-12-07

    这篇文章主要介绍了Python3中函数参数传递方式,结合实例形式较为详细的分析了Python3中函数参数传递的常见操作技巧,需要的朋友可以参考下


  • python如何使用zip同时迭代多个序列

    发布:2021-05-10

    这篇文章主要介绍了python使用 zip 同时迭代多个序列,结合实例形式分析了Python使用zip遍历迭代长度相等与不等的序列相关操作技巧,需要的朋友可以参考下


  • python中的正则表达式,贪婪匹配与非贪婪匹配方式

    发布:2023-04-24

    这篇文章主要介绍了python中的正则表达式,贪婪匹配与非贪婪匹配方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教


  • python定时复制远程文件代码实现

    发布:2020-06-22

    这篇文章主要为大家详细介绍了python定时复制远程文件夹中所有文件,具有一定的参考价值,感兴趣的小伙伴们可以参考一下


  • Python+seaborn实现联合分布图的绘制

    发布:2023-04-06

    联合分布(Joint Distribution)图是一种查看两个或两个以上变量之间两两相互关系的可视化图,在数据分析操作中经常需要用到。本文将通过seaborn实现绘制联合分布图,需要的可以参考一下


  • python3 urllib中urlopen报错的问题解决办法

    发布:2020-03-26

    这篇文章主要介绍了关于解决python3 urllib中urlopen报错问题的相关资料,文中介绍的非常详细,相信对大家具有一定的参考价值,需要的朋友们下面来一起看看吧。


  • Python pandas中read_csv参数示例详解

    发布:2023-04-26

    使用pandas做数据处理的第一步就是读取数据,数据源可以来自于各种地方,csv文件便是其中之一,下面这篇文章主要给大家介绍了关于Python pandas中read_csv参数详解的相关资料,需要的朋友可以参考下


  • spark编程python实例解读

    发布:2023-04-04

    这篇文章主要介绍了spark编程python实例解读,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教


网友讨论