2016-12-06 71 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功能中发现的相关细节。