eval函数

Eval()函数

返回传入字符串的表达式的结果。就是说:将字符串当成有效的表达式 来求值 并 返回计算结果。

eval函数就是实现list、dict、tuple与str之间的转化,同样str函数把list,dict,tuple转为为字符串

eval的语法

  • eval(expression[, globals[, locals]])
  • expression : 表达式。
  • globals : (可选参数)变量作用域,全局命名空间,如果被提供,则必须是一个字典对象。
  • locals : (可选参数)变量作用域,局部命名空间,如果被提供,可以是任何映射对象。

eval有两个可选参数是命名空间,那么什么是命名空间?

命名空间

  • 名称到对象的映射。、
  • python是用命名空间来记录变量的轨迹的,命名空间是一个dictionary,键是变量名,值是变量值。
  • 各个命名空间是独立没有关系的,一个命名空间中不能有重名,但是不同的命名空间可以重名而没有任何影响

命名空间分类

  • python程序执行期间会有2个或3个活动的命名空间(函数调用时有3个,函数调用结束后2个)。、
  • 按照变量定义的位置,可以划分为以下3类:
    1. Local:局部命名空间,每个函数所拥有的命名空间,记录了函数中定义的所有变量,包括函数的入参、内部定义的局部变量。
    2. Global:全局命名空间,每个模块加载执行时创建的,记录了模块中定义的变量,包括模块中定义的函数、类、其他导入的模块、模块级的变量与常量。
    3. Built-in,python自带的内建命名空间,任何模块均可以访问,放着内置的函数和异常。

命名空间的生命周期

  1. Local在函数被调用时才被创建,但函数返回结果或抛出异常时被删除。(每一个递归函数都拥有自己的命名空间)。
  2. Global在模块被加载时创建,通常一直保留直到python解释器退出。
  3. Built-in在python解释器启动时创建,一直保留直到解释器退出。

命名空间创建顺序

  • python解释器启动 –>创建内建命名空间 –> 加载模块 –> 创建全局命名空间 –>函数被调用 ->创建局部命名空间

命名空间销毁顺序

  • 函数调用结束 -> 销毁函数对应的局部命名空间 -> python虚拟机(解释器)退出 ->销毁全局命名空间 ->销毁内建命名空间

python解释器加载阶段会创建出内建命名空间、模块的全局命名空间,局部命名空间是在运行阶段函数被调用时动态创建出来的,函数调用结束会动态销毁的。

全局命名空间存储在一个叫globals()的dict对象中;print (globals())来查看该函数体内的所有变量名和变量值

局部命名空间存储在一个叫locals()的dict对象中。用print (locals())来查看该函数体内的所有变量名和变量值

1
2
3
4
import numpy as np
import pandas as pd
import os,re,random
from datetime import date,time
1
2
locals()

1
globals()

函数的参数

当后两个参数都为空时,很好理解,就是一个string类型的算术表达式,计算出结果即可。等价于eval(expression)。

当locals参数为空,globals参数不为空时,先查找globals参数中是否存在变量,并计算。

当两个参数都不为空时,先查找locals参数,再查找globals参数。

1
2
3
# 无参数:
a = "(1+2)**3"
eval(a)
27
1
2
3
4
# 字符串中包含变量:
a = (1 + 2) ** 3
b = 2**4
eval("a + b")
43
1
2
3
4
# 
c = "(1+2)**3"
d = "2**4"
eval("c + ' ' + d")
'(1+2)**3 2**4'
1
2
3
4
# 字符串转成字典或者列表
eval("[1,3,'a',50,'python']")

eval("{'name':'john','age':'18'}")
[1, 3, 'a', 50, 'python']


{'name': 'john', 'age': '18'}
1
2
3
4
5
6
# 传递全局变量
# 当存在相同的全局变量时,保留最后一个出现的

eval("{'name':'john','age':age}", {"age": 18})

eval("{'name':'john','age':age}", {"age": 18}, {"age": 28})
{'name': 'john', 'age': 18}


{'name': 'john', 'age': 28}
1
2
3
4
# 传递本地变量
# 既有global和local时,变量值先从local中查找
age = 28
eval("{'name':'john','age':age}", {"age": 18}, locals())
{'name': 'john', 'age': 28}
1
2
3
4
5
lst = [i for i in range(20) if i%3==0 and i >0]
lst

eval("lst[3]")
eval("{k:v for v ,k in enumerate(lst)}")
[3, 6, 9, 12, 15, 18]

12

{3: 0, 6: 1, 9: 2, 12: 3, 15: 4, 18: 5}
1
eval('input()')
'1+2*3'
1
2
s = input()
eval(s)
7
1
2
3
4
a = '1 + 2 + 3'
eval(a)

eval('1+2+3')
6

6
1
eval("[i for i in os.listdir() if re.search(r'^\w{3}\.ipynb$',i)]")
['字符串.ipynb', '字符画.ipynb', '解析式.ipynb', '运算符.ipynb']

DataFrame.eval

  • df 有eval
  • 但是其他数据集不可以。list,set,dict,Series
1
2
3
4
5
a = 'np.random.randint(50,100,5)'
eval(a)
dct = {'a':eval(a),'b':eval(a),'c':eval(a),'d':eval(a),'e':eval(a),}
df = pd.DataFrame(dct)
df
array([56, 82, 83, 58, 66])
a b c d e
0 63 96 52 74 93
1 62 53 86 92 62
2 60 75 54 79 88
3 98 66 67 85 68
4 90 87 53 94 54
1
df.eval('a>80')
0    False
1    False
2    False
3     True
4     True
Name: a, dtype: bool
1
df[df.eval('a > 80')]
a b c d e
3 98 66 67 85 68
4 90 87 53 94 54