我正在从不同的软件中运行python脚本(它提供了一个python接口来操纵其数据结构)。
我正在优化我的代码速度,并希望看到我的断言对性能有什么影响。
我无法使用python -O
。我有什么其他选项,以编程方式禁用python代码中的所有断言?变量__debug__
(由-O
标志清除)无法分配给:(
答案 0 :(得分:9)
内置变量[
__debug__
]的值在确定时确定 翻译开始。
因此,如果您无法控制python解释器的启动方式,那么看起来您无法禁用断言。
接下来是其他一些选择:
如果所有的断言语句都是单独出现在行上,那么 也许你可以用
删除它们sed -i 's/assert /pass #assert /g' script.py
请注意,如果其他代码出现在assert之后,这将破坏您的代码。例如,上面的sed命令会将return
注释掉,如下所示:
assert x; return True
会改变程序的逻辑。
如果您有这样的代码,最好手动删除断言。
可能有办法通过解析你的方式以编程方式删除它们
脚本与tokenize
模块,但编写这样的程序
删除断言可能比手动操作花费更多时间
删除断言,特别是如果这是一次性工作。
如果另一个软件接受.pyc文件,则有一个
肮脏的伎俩似乎在我的机器上工作,虽然注意a Python
core developer warns against this(参见ÉricAraujo对2011-09-17的评论)。假设您的脚本名为script.py
。
创建一个名为temp.py的临时脚本:
import script
python -O temp.py
。这会创建script.pyo
。script.py
和script.pyc
(如果存在)
或其他软件正在阅读的目录以查找您的
脚本。script.pyo
- > script.pyc
。现在,当其他软件尝试导入您的脚本时,它会
只找到已移除断言的pyc
文件。
例如,如果script.py
如下所示:
assert False
print('Got here')
然后运行python temp.py
现在会打印Got here
而不是引发AssertionError。
答案 1 :(得分:1)
您可以使用环境变量执行此操作,如this other answer中所述。设置PYTHONOPTIMIZE=1
相当于使用-O
选项启动Python。例如,这适用于Blender 2.78,它嵌入了Python 3.5:
blender --python-expr 'assert False; print("foo")'
PYTHONOPTIMIZE=1 blender --python-expr 'assert False; print("foo")'
第一个命令打印回溯,而第二个命令打印“foo”。
答案 2 :(得分:0)
正如@unutbu所描述的那样,没有正式的方法可以做到这一点。但是,一个简单的策略是在某处定义类似_test
的标志(例如,作为函数的关键字参数,或作为模块中的全局变量),然后在断言语句中包含它,如下所示:
def f(x, _test=True):
assert not _test or x > 0
...
然后,如果需要,您可以在该功能中禁用断言。
f(x, _test=False)