inspect.getsourcelines(object) 显示 OSError if 运行 from python shell 但如果 运行 from a file 则不给出错误

inspect.getsourcelines(object) shows OSError if run from python shell but gives no error if run from a file

我在名为 test.py 的脚本中尝试了此代码片段:

from inspect import *

def f1(p,r):
    """Return f1 score from p,r"""
    return 2*p*r/(p+r)

print(getsourcelines(f1))

如果我 运行 从带有 python3 test.py 的终端,它输出以下内容:

(['def f1(p,r):\n', '\t"""Return f1 score from p,r"""\n', '\treturn 2*p*r/(p+r)\n'], 3)

但是,如果我在 python shell 中逐行 运行 相同的整个脚本,它会抛出一个 OSError。这是我在 python shell 中尝试的方法以及错误:

>>> from inspect import *
>>> 
>>> def f1(p,r):
...     """Return f1 score from p,r"""
...     return 2*p*r/(p+r)
... 
>>> print(getsourcelines(f1))
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/usr/lib/python3.6/inspect.py", line 955, in getsourcelines
    lines, lnum = findsource(object)
  File "/usr/lib/python3.6/inspect.py", line 786, in findsource
    raise OSError('could not get source code')
OSError: could not get source code
>>> 

为什么 inspect.getsourcelines(f1) 在 python shell 中抛出错误,但在 运行 形成文件时却没有?有没有其他方法可以获取在 python shell?

中声明的函数的源代码行

这是预期的行为。 inspect 对内置对象(不是从文件加载)的支持有限。

它在其他函数中是明确的,例如 getsourcefile 文档说:

This will fail with a TypeError if the object is a built-in module, class, or function.

如果不那么明确,getsourcelines 的文档说(强调我的):

The source code is returned as a list of the lines corresponding to the object and the line number indicates where in the original source file the first line of code was found. An OSError is raised if the source code cannot be retrieved.

在当前版本中,getsourcelines尝试在当前源文件中定位函数。由于它无法获取在文件外部声明的函数的当前源文件,因此会引发异常。

根本原因是,当python以交互模式启动时,主模块是内置模块,没有__file__属性。