zoukankan      html  css  js  c++  java
  • Python中两大神器&exec() &eval()

    一、神器1 —— 内置函数eval

    eval是python中的内置函数,它的作用是将字符串变为所对应的表达式,也相当于一个功能代码加双引号变为字符串,而eval又将字符串转为相应的功能,它在使用过程中有绝对的优势,但是也存在使用风险,所以要在程序中正确使用,本人建议不要使用

    eval的语法格式如下:

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

    结合globals和locals看看几个例子

    传递globals参数值为{“age”:1822},
    b = eval("{'name':'linux','age':age}",{"age":1822})
    print(b)
    
    结果:{‘name’: ‘linux’, ‘age’: 1822}
    
    再加上locals变量
    age=18
    b = eval("{'name':'linux','age':age}",{"age":1822},locals())
    print(b)
    
    结果:{'name': 'linux', 'age': 18}
    

    通过上述示例可以看出:

    当只使用全局变量globals,不使用局部变量locals时,查找全局是否存在变量,如果存在则用全局的变量
    如果同时使用全局和局部,优先查找局部locals中的变量,其次在找全局globals中的变量,局部参数中同名变量会覆盖全局中的变量的值,遵循取值顺序(局部—>全局—>内置)

    1.eval强大之处

    更改变量的值

    x = 10
    
    
    def func():
        y = 20
        a = eval('x+y')
        print("a", a)
        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)
    
    
    func()
    
    结果:a 30
         b 3
         c 4
    

    eval函数实现list、dict、tuple与str之间的转化

    字符串转换成列表b = eval("[[1,2], [3,4], [5,6], [7,8], [9,0]]")
    a = "[[1,2], [3,4], [5,6], [7,8], [9,0]]"
    print(type(a))
    b = eval(a)
    print(type(b))
    print(b)
    
    结果:<class 'str'>
         <class 'list'>
         [[1, 2], [3, 4], [5, 6], [7, 8], [9, 0]]
    
    字符串转换成字典b = eval("{1: 'a', 2: 'b'}")
    a = "{1: 'a', 2: 'b'}"
    print(type(a))
    b = eval(a)
    print(type(b))
    print(b)
    
    结果:<class 'str'>
         <class 'dict'>
         {1: 'a', 2: 'b'}
    
    字符串转换成元组b = eval("([1,2], [3,4], [5,6], [7,8], (9,0))")
    a = "([1,2], [3,4], [5,6], [7,8], (9,0))"
    print(type(a))
    b = eval(a)
    print(type(b))
    print(b)
    
    结果:<class 'str'>
       	 <class 'tuple'>
         ([1, 2], [3, 4], [5, 6], [7, 8], (9, 0))
    

    从上边的例子中可以看出,给eval给个字符串,eval给一个表达式返回值,这就是它的好处

    2.eval危险之处

    eval虽然方便,但是要注意安全性,可以将字符串转成表达式并执行,就可以利用执行系统命令,删除文件等操作。
    当使用者不清楚它的危险之处,输入如下:
    eval("__import__('os').system('ls /Users/chunming.liu/Downloads/')")
    
    它其实执行的是如下操作
    os.system('ls /Users/chunming.liu/Downloads/')
    
    那么继续输入:
    eval("__import__('os').system('cat /Users/chunming.liu/Downloads/tls_asimov_cert.pem')")
    
    再来一条删除命令,文件就会消失。比如
    eval("__import__('os').system('rm /Users/chunming.liu/Downloads/车辆转发测试.png')")
    
    所以使用eval,一方面享受他的了灵活性同时,也要注意安全性。

    二、神器2 ——内置函数exec()

    python3中删去了 execfile()方法,使用exec(),它能够执行复杂的代码:

    with open('test1.py','r') as f:
        exec(f.read())
    

    exec格式语法如下:

    exec(object[, globals[, locals]]]
    
    object:必选参数,表示需要被指定的python代码,它必须是字符串或code对象。如果object是一个字符串,该字符串会被先解析为一组python语句,然后再执行。如果object是一个code对象,那么它只是被简单的执行
    globals:可选参数,同eval函数
    locals:可选参数,同eval函数
    返回值:
    exec函数的返回值永远为None
    globals = {'x': 7, 'y': 10, 'lis': ['aa', 'bb', 'cc']}
    locals = {}
    
    a = eval("3*x+4*y", globals, locals)
    print(a)
    
    exec("for i in lis:    print(i)", globals, locals)
    
    结果:61
         aa
         bb
         cc
    

    上述示例中exec()中相当于执行了

    globals = {'x': 7, 'y': 10, 'lis': ['aa', 'bb', 'cc']}
    
    for i in lis:    
    	print(i)
    

    到这里我在跟大家说一下eval()函数与exec()函数的区别:

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

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

  • 相关阅读:
    WIN8开启AHCI的方法终于得到解决。
    Androidx86入门之让你的Androidx86竖屏起来
    Android软件去广告教程
    opencv 3 core组件进阶(2 ROI区域图像叠加&图像混合;分离颜色通道、多通道图像混合;图像对比度,亮度值调整)
    opencv 4 图像处理 (1 线性滤波,非线性滤波)
    opencv 3 core组件进阶(3 离散傅里叶变换;输入输出XML和YAML文件)
    php正则指定字符串内容preg_match函数之说明
    dedecms pagelist标签修改方法
    php后台多用户权限组思路与实现程序代码
    php中获取文件后缀名多种方法
  • 原文地址:https://www.cnblogs.com/shenhongbo/p/11566596.html
Copyright © 2011-2022 走看看