【问题标题】:Disabling python's assert() without -0 flag在没有 -0 标志的情况下禁用 python 的 assert()
【发布时间】:2014-07-05 20:50:56
【问题描述】:

我正在从另一个软件内部运行一个 python 脚本(它提供了一个 python 接口来操作它的数据结构)。

我正在优化我的代码以提高速度,并想看看我的断言对性能有什么影响。

我无法使用python -O。我还有哪些其他选项可以以编程方式禁用 python 代码中的所有断言?变量__debug__(由-O 标志清除)不能分配给:(

【问题讨论】:

    标签: python debugging assert


    【解决方案1】:

    The docs say,

    内置变量 [__debug__] 的值是在 解释器启动。

    因此,如果您无法控制 python 解释器的启动方式,那么您似乎无法禁用断言。

    这里有一些其他选项:

    1. 最安全的方法是手动删除所有断言语句。
    2. 如果您的所有断言语句都单独出现在行上,那么 也许你可以删除它们

      sed -i 's/assert /pass #assert /g' script.py
      

      请注意,如果断言之后有其他代码,这将破坏您的代码。例如,上面的 sed 命令会在如下一行中注释掉 return

      assert x; return True
      

      这会改变你程序的逻辑。

      如果您有这样的代码,最好手动删除断言。

    3. 可能有一种方法可以通过解析您的 带有tokenize 模块的脚本,但编写这样的程序 删除断言可能需要比手动操作更多的时间 删除断言,特别是如果这是一次性工作。

    4. 如果其他软件接受 .pyc 文件,则有一个 尽管注意a Python core developer warns against this(参见 Éric Araujo 于 2011-09-17 的评论),但似乎在我的机器上工作的肮脏技巧。假设您的脚本名为script.py

      • 制作一个名为 temp.py 的临时脚本:

        import script
        
      • 运行python -O temp.py。这将创建 script.pyo
      • script.pyscript.pyc(如果存在)移出PYTHONPATH 或其他软件正在读取的任何目录以找到您的 脚本。
      • 重命名script.pyo --> script.pyc

      现在,当其他软件尝试导入您的脚本时,它会 只找到 pyc 文件,该文件已删除断言。

      例如,如果script.py 看起来像这样:

      assert False
      print('Got here')
      

      然后运行 ​​python temp.py 现在将打印 Got here 而不是引发 AssertionError。

    【讨论】:

    • 小修复:'s/assert/pass #assert/g。否则只有一个assert 语句的if 分支将无法编译:)
    【解决方案2】:

    正如@unutbu 所描述的,没有官方的方法可以做到这一点。然而,一个简单的策略是在某处定义一个类似 _test 的标志(例如,作为函数的关键字参数,或作为模块中的全局变量),然后将其包含在您的断言语句中,如下所示:

    def f(x, _test=True):
        assert not _test or x > 0
        ...
    

    然后,如果需要,您可以在该函数中禁用断言。

    f(x, _test=False)
    

    【讨论】:

      【解决方案3】:

      您可以使用环境变量来执行此操作,如this other answer 中所述。设置PYTHONOPTIMIZE=1 相当于使用-O 选项启动Python。例如,这适用于嵌入 Python 3.5 的 Blender 2.78:

      blender --python-expr 'assert False; print("foo")'
      
      PYTHONOPTIMIZE=1 blender --python-expr 'assert False; print("foo")'
      

      第一个命令打印回溯,而第二个命令只打印“foo”。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2023-03-13
        • 2015-12-10
        • 1970-01-01
        • 2019-05-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多