eval函数 exec函数 compile函数之间的应用

comiple()函数、globals()函数、locals()函数的返回结果可以当作eval()函数与exec()函数的参数使用。

eval()和exec()的重点:
source:

必选参数,可以是字符串,也可以是以个任意的code对象实例(可通过complie函数创建),如果是一个字符串的话,它会被当作一个

(使用globals和locals参数作为全局和本地命名空间的)python表达式进行分析和解释

比如两个字符串之间的值映射关系,但不改变原来字符串的值

x = [1,2,3]

string = 'abc'
# 将一个可迭代对象中的元素赋值给另一个可迭代对象中的元素
for i in range(len(string)):
    exec(string[i]+'='+str(x[i])) # exec难道是提取字符串中的字符

print(a,b,c) # 这个只是单个元素映射 1 2 3
print(string) # abc

# eval(expression, globals=None, locals=None)

eval函数与exec函数的区别:

eval()函数只能计算单个表达式的值,而exec()函数可以动态运行代码段。

eval()函数可以有返回值,而exec()函数返回值永远为None。

globals()函数locals()函数区别:(有点像java中的javadoc将注释生成HTML文档的技术,生成的HTML文档类似于Java的API,易读且清晰明了)这里是返回当前函数的全部标识符
globals()函数以字典的形式返回的定义该函数的模块内的全局作用域下的所有标识符(变量、常量等)
locals()函数以字典的形式返回当前函数内的局域作用域下的所有标识符
如果直接在模块中调用globals()和locals()函数,它们的返回值是相同的

# eval函数

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

# eval(source, globals=None, locals=None, /)
# source:必选参数,可以是字符串,也可以是以个任意的code对象实例(可通过complie函数创建),如果是一个字符串的话,它会被当作一个
# (使用globals和locals参数作为全局和本地命名空间的)python表达式进行分析和解释
# gloabals:必选参数,表示全局命名空间 ; 如果被提供则必须是一个字典对象
# locals:可选参数,如果被提供,可以是任何映射对象。如果参数被忽略,那么它将会取与globals相同的值
"""
如果source是一个code对象,且创建该code对象时,complie函数的mode参数是‘exec’,那么eval()函数的返回值是None;

否则,如果source是一个输出语句,如print(),则eval()返回结果为None;

否则,source表达式的结果就是eval()函数的返回值

"""
x = 10
def func():
    y = 20   #局部变量y
    a = eval("x+y")
    print("a:",a)      #x没有就调用全局变量
    b = eval("x+y",{"x":1,"y":2})     #定义局部变量,优先调用
    print("b:",b)
    c = eval("x+y",{"x":1,"y":2},{"y":3,"z":4})  
    print("c:",c)  
    d = eval("print(x,y)")
    print("d:",d)   #对于变量d,因为print()函数不是一个计算表达式,因此没有返回值
func()


# exec函数 动态执行python代码。也就是说exec可以执行复杂的python代码,而不像eval函数那样只能计算一个表达式的值。
"""
source:必选参数,表示需要被指定的python代码。它必须是字符串或code对象。如果source是一个字符串,该字符串会先被解析为一组python语句,然后执行。如果source是一个code对象,那么它只是被简单的执行。

返回值:

exec函数的返回值永远为None。

 

eval()函数和exec()函数的区别:

eval()函数只能计算单个表达式的值,而exec()函数可以动态运行代码段。

eval()函数可以有返回值,而exec()函数返回值永远为None。

"""
# eval函数

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

# eval(source, globals=None, locals=None, /)
# source:必选参数,可以是字符串,也可以是以个任意的code对象实例(可通过complie函数创建),如果是一个字符串的话,它会被当作一个
# (使用globals和locals参数作为全局和本地命名空间的)python表达式进行分析和解释
# gloabals:必选参数,表示全局命名空间 ; 如果被提供则必须是一个字典对象
# locals:可选参数,如果被提供,可以是任何映射对象。如果参数被忽略,那么它将会取与globals相同的值
"""
如果source是一个code对象,且创建该code对象时,complie函数的mode参数是‘exec’,那么eval()函数的返回值是None;

否则,如果source是一个输出语句,如print(),则eval()返回结果为None;

否则,source表达式的结果就是eval()函数的返回值

"""
x = 10
def func():
    y = 20   #局部变量y
    a = eval("x+y")
    print("a:",a)  # a: 30    #x没有就调用全局变量
    b = eval("x+y",{"x":1,"y":2})     #定义局部变量,优先调用
    print("b:",b)# b: 3 
    c = eval("x+y",{"x":1,"y":2},{"y":3,"z":4})  # c: 4  挑取2个字典中对应的值输出
    print("c:",c)  
    d = eval("print(x,y)") # 10 20 
    print("d:",d) # d: None  #对于变量d,因为print()函数不是一个计算表达式,因此没有返回值
func()


# exec函数 动态执行python代码。也就是说exec可以执行复杂的python代码,而不像eval函数那样只能计算一个表达式的值。
"""
source:必选参数,表示需要被指定的python代码。它必须是字符串或code对象。如果source是一个字符串,该字符串会先被解析为一组python语句,然后执行。如果source是一个code对象,那么它只是被简单的执行。

返回值:

exec函数的返回值永远为None。

 

eval()函数和exec()函数的区别:

eval()函数只能计算单个表达式的值,而exec()函数可以动态运行代码段。

eval()函数可以有返回值,而exec()函数返回值永远为None。

"""
# PYTHON中函数相同一样是可以的
print('\n')
x = 10
def func():
    y = 20
    a = exec("x+y")
    print("a:",a)
    b = exec("x+y",{"x":1,"y":2})
    print("b:",b)
    c = exec("x+y",{"x":1,"y":2},{"y":3,"z":4})
    print("c:",c)
    d = exec("print(x,y)") # 这里的print函数输出了
    print("d:",d)
func()

# globals()函数
# 返回一个表示当前全局标识符表的字典。
# 这永远是当前模块的字典(在一个函数或方法内部,这是指定义该函数或方法的模块,而不是调用该函数或方法的模块)

#locals()
# 更新并返回一个表示当前局部标识符表的字典。
# *变量在函数内部被调用时,会被locals()函数返回;*变量在类累不被调用时,不会被locals()函数返回。
#  locals()返回的字典的内容不应该被改变;如果一定要改变,不应该影响被解释器使用的局部变量和*变量。

"""
globals()函数以字典的形式返回的定义该函数的模块内的全局作用域下的所有标识符(变量、常量等)
locals()函数以字典的形式返回当前函数内的局域作用域下的所有标识符
如果直接在模块中调用globals()和locals()函数,它们的返回值是相同的

"""
# globals and lobals 的功能有点像java中的javadoc
print('\n')
name = 'Tom'
age = 18

def func(x, y):
    sum = x + y
    _G = globals()
    _L = locals()
    print(id(_G), type(_G),  _G)
    print('\n')
    print(id(_L), type(_L), _L)

func(10, 20)


# compile函数
# 将source编译为code对象或AST对象。code对象能够通过exec()函数来执行或者通过eval()函数进行计算求值。
# compile(source, filename, mode[, flags[, dont_inherit]])
"""
source:字符串或AST(Abstract Syntax Trees)对象,表示需要进行编译的Python代码
filename:指定需要编译的代码文件名称,如果不是从文件读取代码则传递一些可辨认的值(通常是用'<string>')
mode:用于标识必须当做那类代码来编译;如果source是由一个代码语句序列组成,则指定mode='exec';
如果source是由单个表达式组成,则指定mode='eval';如果source是由一个单独的交互式语句组成,则指定mode='single'。
另外两个可选参数暂不做介绍
"""
s = """
for x in range(10):
    print(x, end='')
print()
"""
code_exec = compile(s, '<string>', 'exec')
code_eval = compile('10 + 20', '<string>', 'eval')
code_single = compile('name = input("Input Your Name: ")', '<string>', 'single')

a = exec(code_exec)
b = eval(code_eval)

c = exec(code_single)
d = eval(code_single)

print('a: ', a)
print('b: ', b)
print('c: ', c)
print('name: ', name) # 这里name为啥要输出2次
print('d: ', d)
# print('name; ', name)


"""
comiple()函数、globals()函数、locals()函数的返回结果可以当作eval()函数与exec()函数的参数使用。

另外,我们可以通过判断globals()函数的返回值中是否包含某个key来判断,某个全局变量是否已经存在(被定义)。
"""

参考博客https://www.cnblogs.com/yyds/p/6276746.html

上一篇:cisp-pte靶场通关思路分享----综合题篇


下一篇:Docker文件上传与环境变量配置、基本信息查看