2016-12-06 74 views
3

是從更復雜的代碼庫中提取這個簡單的Python程序:檢查拉姆達代碼

#insp.py 
import inspect 
L = lambda x: x+1 
print("L(10)=" + str(L(10))) 
code = inspect.getsource(L) 
print(code) 

作品,如果我在命令行中運行它:

$ python insp.py 

如果我複製和粘貼python解釋器中的每行失敗:

d:\>python 
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:38:48) [MSC v.1900 32 bit (Intel)] on win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import inspect 
>>> L = lambda x: x+1 
>>> print("L(10)=" + str(L(10))) 
L(10)=11 
>>> code = inspect.getsource(L) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
    File "d:\Users\Cimino\AppData\Local\Programs\Python\Python35-32\Lib\inspect.py", line 944, in getsource 
    lines, lnum = getsourcelines(object) 
    File "d:\Users\Cimino\AppData\Local\Programs\Python\Python35-32\Lib\inspect.py", line 931, in getsourcelines 
    lines, lnum = findsource(object) 
    File "d:\Users\Cimino\AppData\Local\Programs\Python\Python35-32\Lib\inspect.py", line 762, in findsource 
    raise OSError('could not get source code') 
OSError: could not get source code 

請注意,使用IPython而不是普通的Python解釋器,它的工作原理!

有人知道爲什麼嗎?

我在Windows7下使用Python 3.5 32位。

+0

我想這是因爲檢查模塊實際上去尋找解釋器跟蹤的源文件。注意接口也可以給你行號,定義之前的註釋等。當你在REPL中時,這些都不存在。我想象IPython會做一些魔術來確保在交互式案例中檢查能夠正常工作。 – pvg

回答

2

它在IPython中工作,因爲它使用linecache模塊緩存您在此處輸入的每個命令。

例如:

$ ipy ## Equivalent to ipython --classic 
Python 2.7.10 (default, Jul 30 2016, 18:31:42) 
Type "copyright", "credits" or "license" for more information. 

IPython 3.0.0 -- An enhanced Interactive Python. 
?   -> Introduction and overview of IPython's features. 
%quickref -> Quick reference. 
help  -> Python's own help system. 
object? -> Details about 'object', use 'object??' for extra details. 
>>> print a 
Traceback (most recent call last): 
    File "<ipython-input-1-9d7b17ad5387>", line 1, in <module> 
    print a 
NameError: name 'a' is not defined 

通知的<ipython-input-1-9d7b17ad5387>部分在這裏,這是特定於IPython的東西。在普通的Python殼,你會看到<stdin>

$ python 
Python 2.7.10 (default, Jul 30 2016, 18:31:42) 
[GCC 4.2.1 Compatible Apple LLVM 8.0.0 (clang-800.0.34)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> print a 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
NameError: name 'a' is not defined 

現在讓我們來運行代碼:

>>> import inspect 
>>> L = lambda x: x+1 
>>> code = inspect.getsource(L) 

時間去找出相關L文件名:

>>> L.func_code.co_filename 
'<ipython-input-2-0c0d6f325784>' 

現在讓我們來看看我們的源文件爲linecache.cache

>>> import linecache 
>>> linecache.cache[L.func_code.co_filename] 
(18, 1481047125.479239, [u'L = lambda x: x+1\n'], '<ipython-input-2-0c0d6f325784>') 

因此,使用此信息IPython能夠找到所需的源代碼,但Python shell不會因爲它不存儲任何信息。


如何inspect獲取源可以在源代碼getsourcefilefindsource功能中發現的相關細節。