V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
MiketsuSmasher
V2EX  ›  程序员

eval()和 exec()这类语句存在的意义是什么?

  •  
  •   MiketsuSmasher · 2021-11-14 16:57:14 +08:00 · 5106 次点击
    这是一个创建于 1084 天前的主题,其中的信息可能已经有所发展或是发生改变。
    27 条回复    2021-11-16 19:36:52 +08:00
    ipwx
        1
    ipwx  
       2021-11-14 17:19:20 +08:00
    通过可信 dsl 产生程序然后运行吧。。。
    ipwx
        2
    ipwx  
       2021-11-14 17:20:07 +08:00
    直接字符串拼接然后运行容易被注入,但是你可以自己实现一套简单的编译器,然后编译成 host 语言运行
    eason1874
        3
    eason1874  
       2021-11-14 17:34:12 +08:00
    写个稍微复杂一点的模板引擎你就知道了

    动态输入代码可以提供很高的灵活性
    pythonee
        4
    pythonee  
       2021-11-14 17:46:55 +08:00
    @ipwx 你是指自举?
    Mac
        5
    Mac  
       2021-11-14 17:48:46 +08:00
    我用在给客人自定义模版上,内网环境下还是挺好用的
    ch2
        6
    ch2  
       2021-11-14 17:54:42 +08:00
    用二进制或者脚本创建子进程
    ipwx
        7
    ipwx  
       2021-11-14 18:02:27 +08:00
    @pythonee 不是自举。

    模板引擎、动态执行代码,etc 。
    ipwx
        8
    ipwx  
       2021-11-14 18:03:17 +08:00
    很多需要繁琐的 if-else factory 设计模式的,用动态代码生成,有时候就很容易解决了。

    退一万步,JIT 这东西知道吧?相当于它根据 JVM bytecode 产生了机器码。某种意义上也算是 CPU 的 eval 了。
    wanguorui123
        9
    wanguorui123  
       2021-11-14 18:21:26 +08:00
    元编程
    rayhy
        10
    rayhy  
       2021-11-14 21:14:24 +08:00
    只要执行的字符串可控还是挺有用的,用来实现一些黑魔法。
    djFFFFF
        11
    djFFFFF  
       2021-11-14 21:16:33 +08:00
    举个例子,自己写一个 github action ,肯定就要用到 eval ,exec 这些方法
    ClericPy
        12
    ClericPy  
       2021-11-14 22:12:40 +08:00
    exec 日常模版解析传入 UDF...

    eval 的话, 有时候动态传入参数想保留数据类型, 又懒得用 JSON...
    GeruzoniAnsasu
        13
    GeruzoniAnsasu  
       2021-11-14 22:22:20 +08:00   ❤️ 1
    自古以来,程序是程序,数据是数据,程序处理数据但数据不能变成程序的一部分。

    eval 打破了这个限制
    dangyuluo
        14
    dangyuluo  
       2021-11-15 00:52:10 +08:00
    没说语言,C++的话没有 exec 估计现在计算机体系不复存在了
    ysc3839
        15
    ysc3839  
       2021-11-15 00:54:04 +08:00   ❤️ 2
    @GeruzoniAnsasu 自古以来就没有这样的限制,图灵机是不分程序和数据的,冯诺依曼结构也不分程序存储和数据存储,哈佛结构有这种限制,但是长期以来就不是主流。现代 CPU 为了安全性加入了内存权限,但也和哈佛结构有本质区别。
    morewe
        16
    morewe  
       2021-11-15 01:00:07 +08:00
    比如给自己本地用的 web 工具等不需要考虑安全,只需要考虑方便的特殊场景。
    GeruzoniAnsasu
        17
    GeruzoniAnsasu  
       2021-11-15 01:44:56 +08:00
    @ysc3839 怎么说呢,理论模型从理论上已经是完备的,所以体现不出来我想表达的点,就比如我想说「图灵机并不能把自己的状态喂给另一个图灵机」但作为理论,图灵机完全可以按照纸带的要求把上一个状态写到纸带上。

    dany813
        18
    dany813  
       2021-11-15 09:02:53 +08:00
    eval 大法好啊
    Shazoo
        19
    Shazoo  
       2021-11-15 09:31:04 +08:00
    eval 可以将 repr 序列化的数据结构还原。持久化数据结构蛮好用的。只要把控住数据源,不用脏数据,就没问题。
    cairnechen
        20
    cairnechen  
       2021-11-15 09:35:21 +08:00
    昨天安装 homebrew 的时候发现用到了 eval
    VtoExtension
        21
    VtoExtension  
       2021-11-15 11:23:37 +08:00
    脚本语言大都有这个共性,调试会方便。但是在生产环境 eval=evil
    fgwmlhdkkkw
        22
    fgwmlhdkkkw  
       2021-11-15 15:14:42 +08:00
    Python 的模板引擎都是 eval……
    monetto
        23
    monetto  
       2021-11-15 17:24:15 +08:00
    说一个稍微偏一些的吧...有的时候做装饰器的时候,有一些动态类型判断,PyCharm 可能会抽风,直接调试运行会提示类型检查不通过。这时候把条件判断表达式换成 eval 的就可以欺骗过 PyCharm 。
    vkingsea
        24
    vkingsea  
       2021-11-16 11:07:27 +08:00
    给你举个具体例子,
    比如你使用 protobuf ,传递一个具体的消息名,现在需要用这个名字构造一个对应的消息体:

    func = eval("Hello_pb2.LoginRequest")
    request = func()
    request.serverId = 0
    request.token = "i am vkingsea"
    send(request)
    aguesuka
        25
    aguesuka  
       2021-11-16 13:08:19 +08:00
    @monetto alt + enter suppress warring for statement. 这样相当于掩耳盗铃
    monetto
        26
    monetto  
       2021-11-16 16:06:01 +08:00
    @aguesuka 总不能要求所有人都这样来一遍吧...
    aguesuka
        27
    aguesuka  
       2021-11-16 19:36:52 +08:00   ❤️ 1
    @monetto
    虽然手边没有 pycharme, 但是我猜它的 suppress warning type hint 是这样实现的
    https://www.python.org/dev/peps/pep-0484

    Compatibility with other uses of function annotations
    A number of existing or potential use cases for function annotations exist, which are incompatible with type hinting. These may confuse a static type checker. However, since type hinting annotations have no runtime behavior (other than evaluation of the annotation expression and storing annotations in the __annotations__ attribute of the function object), this does not make the program incorrect -- it just may cause a type checker to emit spurious warnings or errors.

    To mark portions of the program that should not be covered by type hinting, you can use one or more of the following:

    a # type: ignore comment;
    a @no_type_check decorator on a class or function;
    a custom class or function decorator marked with @no_type_check_decorator.
    For more details see later sections.

    In order for maximal compatibility with offline type checking it may eventually be a good idea to change interfaces that rely on annotations to switch to a different mechanism, for example a decorator. In Python 3.5 there is no pressure to do this, however. See also the longer discussion under Rejected alternatives below.
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   986 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 27ms · UTC 20:18 · PVG 04:18 · LAX 13:18 · JFK 16:18
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.