2014-03-24 74 views
4

我試圖確保在使用-O時python不執行斷言。然而,我的測試程序表明它始終執行。我在命令行中特別使用了-O,並且在運行setup.py時使用-O進行構建和安裝。在我提交錯誤報告之前,我想確保我沒有做任何新手錯誤...python斷言與-O

那麼,我需要做一些別的或不同的事情,使斷言是而不是執行?

我簡單的腳本:當獨立運行

print __debug__ 

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

assert(False) 

作品。打印:

False 
False branch 

當我複製主程序這個片段(我可以不包括這裏...)我得到:

False 
True branch 
AssertionError 

我心亂如麻怎麼能進來的。這是在Mac上的Python 2.7.6。 (很抱歉的Mac上,我不得不使用它的工作。)

+2

在運行實際程序時使用'-O'。假設你的程序叫做'Script.py',在命令行中你會說'Python -O Script.py' – CoryKramer

+4

發佈了一些代碼,最好是[Short,Self Contained,Correct Example](http://sscce.org) –

+0

'-O'標誌**會放棄斷言。你必須使用'-O'來運行一個高級腳本,而不是最後一個腳本。 – slezica

回答

3

你可以實現你通過與-O標誌運行.pyc文件直接描述的效果。這是對事情應該工作的方式的濫用。你想要麼:

  1. 運行.py文件有或沒有-O標誌(通常的做法),或
  2. 運行.pyc文件沒有-O標誌,或
  3. 運行.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適當。

+0

我被指控執行.pyc和.pyo文件。我的問題是如果我確實有罪,我不知道如何避免。在我運行的目錄中沒有.pyc或.pyo只有.py。我正在指定.py。當然,我的確有模塊編譯和安裝distutils。不過,我認爲通過在這些編譯中使用-O運行,我可以得到正確的編譯結果。仍然完全困惑如何編譯沒有斷言。 – Matyas

+0

distutils安裝的任何部分是否刪除.py文件,只保留.pyc文件?這可能是你的問題的原因。或者,你的所有.pyc文件旁邊是否有.py文件?如果後者,這些.py文件可能由於某種原因(權限等)而無法讀取? *不知何故,*它看起來非常像Python未能找到模塊的.py文件,而是正在拾取.pyc文件。 –

+0

順便說一句,我並沒有指責你任​​何事情:只是表現出一種情況(以及我能想到的唯一情況),你可能會看到你描述的效果。如果答案沒有幫助,我會很樂意刪除它。 –