2015-09-09 45 views
2

使用Python 3,dis.dis()工作很好地解析字符串包含for循環語法:的Python 2 dis.dis()不能解析字符串包含`for`循環語法

>>> import dis 
>>> dis.dis('for _ in range(10): pass') 
    1   0 SETUP_LOOP    20 (to 23) 
       3 LOAD_NAME    0 (range) 
       6 LOAD_CONST    0 (10) 
       9 CALL_FUNCTION   1 (1 positional, 0 keyword pair) 
      12 GET_ITER 
     >> 13 FOR_ITER     6 (to 22) 
      16 STORE_NAME    1 (_) 
      19 JUMP_ABSOLUTE   13 
     >> 22 POP_BLOCK 
     >> 23 LOAD_CONST    1 (None) 
      26 RETURN_VALUE 

在Python 2,它產生string index out of range錯誤:

In [30]: dis.dis('for _ in range(10): pass') 
--------------------------------------------------------------------------- 
IndexError        Traceback (most recent call last) 
<ipython-input-30-b7c7c1c77064> in <module>() 
----> 1 dis.dis('for _ in range(10): pass') 

/usr/lib/python2.7/dis.pyc in dis(x) 
    43   disassemble(x) 
    44  elif isinstance(x, str): 
---> 45   disassemble_string(x) 
    46  else: 
    47   raise TypeError, \ 

/usr/lib/python2.7/dis.pyc in disassemble_string(code, lasti, varnames, names, constants) 
    110 def disassemble_string(code, lasti=-1, varnames=None, names=None, 
    111      constants=None): 
--> 112  labels = findlabels(code) 
    113  n = len(code) 
    114  i = 0 

/usr/lib/python2.7/dis.pyc in findlabels(code) 
    164   i = i+1 
    165   if op >= HAVE_ARGUMENT: 
--> 166    oparg = ord(code[i]) + ord(code[i+1])*256 
    167    i = i+2 
    168    label = -1 

IndexError: string index out of range 

即使在包裝正規的語法功能for循環並沒有幫助:

def test(): 
    for _ in range(10): 
     pass 

dis.dis('test') 
<The same error> 

這是一個錯誤或期望的行爲記錄在其他地方嗎?

軟件版本

$ python2 -V 
Python 2.7.9 

$ python3 -V 
Python 3.4.2 

$ cat /etc/os-release 
PRETTY_NAME="Debian GNU/Linux 8 (jessie)" 
NAME="Debian GNU/Linux" 
VERSION_ID="8" 
VERSION="8 (jessie)" 
ID=debian 
HOME_URL="http://www.debian.org/" 
SUPPORT_URL="http://www.debian.org/support/" 
BUG_REPORT_URL="https://bugs.debian.org/" 

回答

6

Python 2中的dis.dis不服用含有Python代碼作爲參數字符串,它需要包含字節碼或函數的字符串。

最好的辦法是這樣的:

>>> def test(): 
...  for _ in range(10): 
...   pass 
... 
>>> 
>>> import dis 
>>> dis.dis(test) 
    2   0 SETUP_LOOP    20 (to 23) 
       3 LOAD_GLOBAL    0 (range) 
       6 LOAD_CONST    1 (10) 
       9 CALL_FUNCTION   1 
      12 GET_ITER 
     >> 13 FOR_ITER     6 (to 22) 
      16 STORE_FAST    0 (_) 

    3   19 JUMP_ABSOLUTE   13 
     >> 22 POP_BLOCK 
     >> 23 LOAD_CONST    0 (None) 
      26 RETURN_VALUE 
+0

另一種方法是在sting上調用'compile'(使用像「」'和''exec「這樣的其他構造文件名作爲其他參數),並將代碼對象返回給'dis.dis '。 – Blckknght

+0

嗯,我搞砸了我的測試,我在Python 3 shell中,並認爲我是在Python 2 shell中。我從中讀取了'dis.dis'文檔字符串。 – cuonglm

相關問題