python 里面的eval exec 还有compile

发布时间 2024-01-12 22:45:19作者: PKGAME

一、简介

二、操作

三、问题

 

一、简介

  eval exec 方法是python里面内置的方法,用于将字符串代码或者code对象,进行执行的方法。

  参考至:这里

二、操作

  1 eval

  计算指定表达式的值。也就是说它要执行的python代码只能是单个表达式(注意eval不支持任何形式的赋值操作),而不能是复杂的代码逻辑。会有返回值的

  1.1 传参总览

eval(expression, globals=None, locals=None)
  • expression:必选参数,可以是字符串,也可以是一个任意的code对象实例(可以通过compile函数创建)。如果它是一个字符串,它会被当作一个(使用globals和locals参数作为全局和本地命名空间的)Python表达式进行分析和解释。
  • globals:可选参数,表示全局命名空间(存放全局变量),如果被提供,则必须是一个字典对象。
  • locals:可选参数,表示当前局部命名空间(存放局部变量),如果被提供,可以是任何映射对象。如果该参数被忽略,那么它将会取与globals相同的值。

  要注意的是,eval 的表达式里面不能有赋值操作,也就是等号,不然会报错

  1.1.1 globals locals 实例

a = 1
b = 2
an1 = eval('a+b')
an2 = eval('a+b', {'a':3, 'b':4})
an3 = eval('a+b', {'a':3, 'b':4}, {'a':5, 'b':6})
print(an1)
print(an2)
print(an3)

  结果

3
7
11

  当没有globals和locals时, eval 会从当前域里面找参数, 有globals 优先于当前域, locals优先于globals 

  1.1.2 赋值错误实例

eval('a=1')
Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    eval('a=1')
  File "<string>", line 1
    a=1
     ^
SyntaxError: invalid syntax

  

  2. exec 

  动态执行Python代码。也就是说exec可以执行复杂的Python代码,而不像eval函数那么样只能计算一个表达式的值。返回值为空

  2.1 传参总览

exec(object[, globals[, locals]])
  • expression:必选参数,表示需要被指定的Python代码。它必须是字符串或code对象。如果object是一个字符串,该字符串会先被解析为一组Python语句,然后在执行(除非发生语法错误)。如果object是一个code对象,那么它只是被简单的执行。
  • globals:与eval 相同。
  • locals:与eval 相同

  2.1.1 exec  实例

a = 1
b = 2
c = 3
an1 = exec('a+b')
##返回空值
print(an1)
exec('a = a+b+c')
##执行了表达式 
print(a)
long_code = """
index = 0
for item in range(10):
    index += item
print(index)
"""
an3 = exec(long_code)
print(an3)

  结果

None
6
45
None

  2.1.2 设置作用域错误使用

a = 1
b = 2
exec('a = a+b')
##没定义作用域,会修改a的值
print(a)
exec('a = a+b' ,{'b':4})
##如果定义了作用域,那么外部的域就失效了,这个运算会报错,找不到a
print(a)

  结果

3
Traceback (most recent call last):
  File "C:/Users/Administrator/Desktop/test.py", line 9, in <module>
    exec('a = a+b' ,{'b':4})
  File "<string>", line 1, in <module>
NameError: name 'a' is not defined

  3 compile

  严格意义上来将,它的作用是不同于 eval 和exec的, 它只是他们的一个参数生成器

  3.1 传参总览

compile(source, filename, mode, flags=0, dont_inherit=False, optimize=-1)

 

  • source:字符串或AST对象,表示需要进行编译的python代码
  • filename:指定需要编译的代码文件,如果不是文件读取代码则传递一些可辨认的值.
  • mode:用于标识必须当做那类代表来编译; 如果source是由一个代码语句序列组成,则指定mode='exec’,

  3.1.1 使用实例

a = 1
b = 2
code_eval = compile('a + b', '<string>', 'eval')   
code_exec = compile('a = a+b', '<string>', 'exec') 
an1 = eval(code_eval)
print(an1)
exec(code_exec)
print(a)

  结果

3
3

  3.1.2 关于AST对象

  Abstract Syntax Trees即抽象语法树。Ast是python源码到字节码的一种中间产物,借助ast模块可以从语法树的角度分析源码结构。

  在 python 中,我们可以通过自带的 ast 模块来对解析遍历语法树,通过ast.parse()可以将字符串代码解析为抽象语法树,然后通过ast.dump()可以打印这棵语法树。

import ast
root_node = ast.parse("print('hello world')")
 
print(root_node)
print(ast.dump(root_node, indent=4))

  结果

<ast.Module object at 0x000001B87F303490>
Module(
    body=[
        Expr(
            value=Call(
                func=Name(id='print', ctx=Load()),
                args=[
                    Constant(value='hello world')],
                keywords=[]))],
    type_ignores=[])

  参考至:这里

  详细有关python的ast的内容可以看这里: 去看看

三、问题

  1. 怎么查看当前域的参数

  globals()  和 locals()  ,可以返回当前所有参数的列表

g = globals()
g
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/Administrator/Desktop/test.py', 'a': 1, 'b': 2, 'code_eval': <code object <module> at 0x0000019B1ADEF290, file "<string>", line 1>, 'an1': 3, 'g': {...}}
l = locals()
l
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, '__file__': 'C:/Users/Administrator/Desktop/test.py', 'a': 1, 'b': 2, 'code_eval': <code object <module> at 0x0000019B1ADEF290, file "<string>", line 1>, 'an1': 3, 'g': {...}, 'l': {...}}