【问题标题】:Python: Is exec always bad practice and if so why not deprecated [closed]Python:exec 总是不好的做法,如果是,为什么不弃用 [关闭]
【发布时间】:2014-02-28 11:46:17
【问题描述】:

有人能想出一个使用 exec 的良好实践示例吗?

如果总有更高效、更安全的方式来替代 exec,为什么 python 不弃用 exec?

【问题讨论】:

  • 转到相关问题Why should exec() and eval() be avoided?26 In Python, why doesn't exec work in a function with a subfunction?
  • @GrijeshChauhan 虽然有几个问题解释了为什么eval/exec 通常是一种不好的做法,但没有实际好的做法的例子,所以在我看来这是一个有效的问题
  • @goncalopp 你是对的......
  • 再举一个例子:我做了一个小的“框架”,它通过模拟模块的依赖关系来完全解耦它们,从而允许测试不可测试的部分。即,我正在即时编写代码,其行为大多与原始代码相似,但在某些方面。如果没有 exec,这是不可能的。

标签: python python-exec


【解决方案1】:

正如other questions 中所述,eval/exec 被认为是不好的做法,因为它们通常被滥用来完成不需要的任务,从而导致潜在的安全问题和糟糕的编程。

然而,这些机制有一些有效的用途,它们公开了其他地方没有的重要功能 - 在运行时执行任意代码。

例如,假设您要编写一个可以自我更新的应用程序。您可以从使用 exec 运行的远程 URL 获取脚本并将您的应用程序更新到最新版本。虽然这样做本身会带来很大的安全隐患,但通过使用数字签名来确保流程安全并不难。

您可以在code modulesource 中找到另一个常见用途:在运行时执行用户输入的代码以进行调试。

【讨论】:

    【解决方案2】:

    不,eval 和相关工具在任何方面都总是很糟糕

    只有当它们被表示为带有常规、位置或关键字参数的常规函数​​(不是魔术*args**keywords args)时,许多事情才能正常工作。除了eval 之外,没有办法动态创建具有所需参数集的函数。

    有关如何使用它的一个很好的例子,请检查collections.namedtuple 的实现。尽管没有eval 也可以创建这样的类工厂,但是它定义的所有函数,尤其是__new___replace,都会有无用的帮助文本,并且没有它会是一个不太方便的工具.更糟糕的是,非评估实现几乎肯定会SLOWER

    另一个更全面地使用eval 的例子是精巧的decorator 库,它在一系列工具中推广了这种做法,允许您动态创建具有特定函数签名的函数;它在内部使用eval

    【讨论】:

    • 嗯?您可以使用types.FunctionType 动态创建函数并传入代码对象。当然,我猜当你compile你在后台使用exec的代码对象时。
    • 是的,compiletypes.CodeType 具有 evalexec 的所有优点和缺点。但是,如果您以这种方式动态创建函数,您可能应该使用eval 而不是显式创建字节码,因为您必须评估的python 可以跨实现移植,但字节码黑客通常不是。例如,types.CodeType 的签名是实现定义的。
    • 继承collections.Callable 可能更可取,出于所有实际目的,可调用类是一个函数。我同意这个答案,但我确实质疑这句话的正确性“除了 eval,没有办法动态创建具有所需参数集的函数。”
    • @wim:我对一个反例感兴趣。具体来说,你能告诉我一个x,它满足inspect.getargspec(x(y)) == inspect.getargspec(eval('lambda {0}: ({0})'.format(', '.join(y)))),其中y是一个字符串列表(例如y = ['foo', 'bar', 'baz']
    猜你喜欢
    • 2015-06-21
    • 2014-02-01
    • 1970-01-01
    • 2016-05-30
    • 1970-01-01
    • 1970-01-01
    • 2020-05-19
    • 2010-09-26
    • 2010-10-22
    相关资源
    最近更新 更多