gpt4 book ai didi

python断言用-O触发

转载 作者:太空宇宙 更新时间:2023-11-03 11:04:55 25 4
gpt4 key购买 nike

我试图确保在使用 -O 时 python 不执行断言。然而,我的测试程序表明它总是被执行。我特别在命令行上使用了 -O,并且在运行 setup.py 时使用了 -O 来构建和安装。在我提交错误报告之前,我想确保我没有犯任何新手错误...

那么我是否需要做一些其他的事情或不同的事情来使断言被执行?

我的简单脚本:

print __debug__

if __debug__:
print "True branch"
else:
print "False branch"

assert(False)

独立运行时有效。打印:

False
False branch

当我在主程序中复制这段代码时(我不能在此处包含...)我得到:

False
True branch
AssertionError

我完全不明白这是怎么发生的。这个 Python 2.7.6 在 Mac 上。 (对 Mac 感到抱歉,我必须用它来工作。)

最佳答案

您可以通过使用 -O 标志直接运行.pyc 文件来实现您描述的效果。这是对事物运作方式的滥用。您想要:

  1. 运行带有或不带有-O 标志(通常的方法)的.py 文件,或者
  2. 运行 .pyc 文件不带 -O 标志,或者
  3. 使用 -O 标志运行 .pyo 文件。

如果您运行带有 -O 标志的 .pyc 文件,或没有它的 .pyo 文件,您将获得这样的惊喜。

发生的事情是,在编译时,窥孔优化器已经优化掉了 if __debug__ 分支,所以 .pyc.pyo 文件将无条件执行适当的分支。然后,当您使用错误的 -O 规范运行时,您将使用与编译时应用的优化不匹配的 __debug__ 值运行。

有一个similar issue不久前在 Python 问题跟踪器上进行了报告,尽管这是相反的情况:有人在不使用 -O 标志的情况下运行 .pyo 文件。

一个简单的例子:假设我在当前目录中有一个有点像你的名为“debug_example.py”的文件:

noether:Desktop mdickinson$ cat debug_example.py
def main():
print "__debug__ is {}".format(__debug__)
if __debug__:
print "__debug__ is True"
else:
print "__debug__ is False"

if __name__ == '__main__':
main()

如果我们直接执行文件,有或没有 -O 标志,我们都会看到预期的结果:

noether:Desktop mdickinson$ python2 debug_example.py
__debug__ is True
__debug__ is True
noether:Desktop mdickinson$ python2 -O debug_example.py
__debug__ is False
__debug__ is False

现在让我们使用方便的 py_compile 将此文件编译为“debug_example.pyc”文件模块。 (在您的情况下,此编译可能作为 setup.py 安装的一部分执行。):

noether:Desktop mdickinson$ python2 -m py_compile debug_example.py
noether:Desktop mdickinson$ ls -l debug_example.pyc
-rw-r--r-- 1 mdickinson staff 350 24 Mar 21:41 debug_example.pyc

现在我们执行 debug_example.pyc 文件,但是(错误地)使用了 -O 标志,Python 感到困惑:

noether:Desktop mdickinson$ python2 -O debug_example.pyc
__debug__ is False
__debug__ is True

我们可以使用Python's dis module查看模块内的字节码:

Python 2.7.6 (default, Nov 18 2013, 15:12:51) 
[GCC 4.2.1 Compatible Apple LLVM 5.0 (clang-500.2.79)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> import debug_example
>>> import dis
>>> dis.dis(debug_example)
Disassembly of main:
2 0 LOAD_CONST 1 ('__debug__ is {}')
3 LOAD_ATTR 0 (format)
6 LOAD_GLOBAL 1 (__debug__)
9 CALL_FUNCTION 1
12 PRINT_ITEM
13 PRINT_NEWLINE

4 14 LOAD_CONST 2 ('__debug__ is True')
17 PRINT_ITEM
18 PRINT_NEWLINE
19 LOAD_CONST 0 (None)
22 RETURN_VALUE

请注意,那里根本没有与 if 语句对应的字节码:我们看到了 '__debug__ is True' 的无条件打印。

解决方案:不要直接执行.pyc.pyo 文件:执行.py 文件,让Python 自己判断是否根据需要使用 .pyc.pyo

关于python断言用-O触发,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22619681/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com