你可以實現你通過與-O
標誌運行.pyc
文件直接描述的效果。這是對事情應該工作的方式的濫用。你想要麼:
- 運行
.py
文件有或沒有-O
標誌(通常的做法),或
- 運行
.pyc
文件沒有的-O
標誌,或
- 運行
.pyo
文件與-O
標誌。
如果你運行一個.pyc
文件與-O
標誌,或.pyo
文件沒有它,你會得到這樣一個驚喜。
發生了什麼事是,在編譯時窺視孔優化器已經被優化掉的樹枝if __debug__
,所以.pyc
或.pyo
文件將無條件地執行相應的分支。然後,當您運行的錯誤規格爲-O
時,將運行的值爲__debug__
,與編譯時應用的優化不匹配。
在Python問題追蹤器上報告了一段similar issue,儘管這是相反的情況:有人在不使用-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
現在,讓我們這個文件編譯成」 debug_example.pyc」文件中使用得心應手py_compile
模塊(在你的情況下,該彙編可能被作爲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
現在我們使用-O
標誌執行debug_example.pyc
文件,但(錯誤地),和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
適當。
在運行實際程序時使用'-O'。假設你的程序叫做'Script.py',在命令行中你會說'Python -O Script.py' – CoryKramer
發佈了一些代碼,最好是[Short,Self Contained,Correct Example](http://sscce.org) –
'-O'標誌**會放棄斷言。你必須使用'-O'來運行一個高級腳本,而不是最後一個腳本。 – slezica