如何处理“inspect.getsource”的限制 - 或者如何仅获取函数的源?

2024-02-25

我一直在玩inspectPython 标准库中的模块。

下面的例子工作得很好(假设inspect已导入):

def foo(x, y):
    return x - y
print(inspect.getsource(foo))

...将打印def foo(x, y):\n return x - y\n and ...

bar = lambda x, y: x / y
print(inspect.getsource(bar))

...将打印bar = lambda x, y: x / y\n。到目前为止,一切都很好。然而,在下面的例子中事情变得有点奇怪:

print(inspect.getsource(lambda x, y: x / y))

...将打印print(inspect.getsource(lambda x, y: x / y)) and ...

baz = [2, 3, lambda x, y: x / y, 5]
print(inspect.getsource(baz[2]))

...将打印baz = [2, 3, lambda x, y: x / y, 5].

该模式似乎是所有相关的源代码lines无论上下文如何,都会返回getsource。这些行中的其他所有内容(在我的例子中,除了所需的函数源/定义之外)也包括在内。是否有另一种“替代”方法,它允许提取代表函数源代码的内容 - 并且仅代表其源代码 - 最好以某种匿名方式?


EDIT (1)

def foo(x, y):
    return x - y
bar = [1, 2, foo, 4]
print(inspect.getsource(bar[2]))

...将打印def foo(x, y):\n return x - y\n.


不幸的是,这是不可能的inspect,并且如果不再次解析(和编译)源代码,它就不可能工作。inspect's getsource https://github.com/python/cpython/blob/3.7/Lib/inspect.py#L967-L974方法相当有限:它使用getsourcelines https://github.com/python/cpython/blob/3.7/Lib/inspect.py#L946-L965然后打电话findsource https://github.com/python/cpython/blob/3.7/Lib/inspect.py#L760-L831,这实际上会打开你的对象,直到我们最终得到一个PyCodeObject https://github.com/python/cpython/blob/3.7/Include/code.h#L20-L51.

此时,我们正在处理已编译的字节码。原始来源留下的所有内容是片段和提示,例如 https://github.com/python/cpython/blob/3.7/Include/code.h#L20-L51 as co_firstlineno:

/* Bytecode object */
typedef struct {
    /* ... other fields omitted ... */
    int co_firstlineno;         /* first source line number */
    PyObject *co_code;          /* instruction opcodes */
    /* ... other fields omitted ... */
} PyCodeObject;

顺便说一句,类似于PyCodeObject, a PyFrameObject也只包含一个f_lineno https://github.com/python/cpython/blob/3.7/Include/frameobject.h#L42, but no列,这解释了为什么回溯仅包含文件名和行:该列未编译到字节码中。

由于字节码不包含比(第一)行更具体的区域,因此不可能从中获取确切的源位置inspect或任何其他仅使用(公共)字节码信息而无需进一步解析的库。这也适用于仅使用字节码的任何其他选项,例如pickle.

inspect使用公开信息(co_firstlineno) and 然后只搜索函数的合适开头和周围块的结尾 https://github.com/python/cpython/blob/3.7/Lib/inspect.py#L826。然而,inspect is almost在那里,但它只发现any块,而不是正确的块 https://github.com/python/cpython/blob/3.7/Lib/inspect.py#L935,和它cannot找到当前正确的一个。inspect标记整行并且不从正确的变体开始,它也不知道正确的相应源代码区域。

假设我们有

plus, minus, mult = lambda x: x + 1, lambda y: y - 1, lambda z: z * 5

我们想要的只是minus。由于字节码不包含co_firstcolumn,我们只有全系列产品。我们可以解析所有 lambda,但我们仍然不知道哪个 lambda 适合我们的co_code。我们需要再次编译它们并检查它们的字节码是否适合原始字节码。

最后,我们必须这样做:再次解析源代码并找到正确的PyCodeObject。如果我们至少有一个起始列号,那就容易多了,因为我们可以只使用语法分析,但 AST 只保留目前的行数 https://devguide.python.org/compiler/#abstract-syntax-trees-ast。所以要么inspect需要一个大补丁,或者字节码需要包含编译对象的起始列。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何处理“inspect.getsource”的限制 - 或者如何仅获取函数的源? 的相关文章

随机推荐

  • 如何在这个程序中使用枚举?

    f open Student dat r opens Student dat file roll1 input Enter roll to be found to find a record in a list using a roll n
  • 移动浏览器上的“自动播放”HTML5 音频播放器

    我正在为移动用户创建一个 HTML5 音乐网站 目标是让它完全在移动浏览器中运行 问题是 当用户选择要播放的曲目时 他们会被带到 播放器 页面 然后我在 HTML5 音频元素中进行 AJAX 并将 autoplay 属性设置为 true 这
  • jQuery 从元素中删除特定文本

    我想从我的网站的元素中删除文本 By 我希望文本的其余部分保留在那里 我怎样才能用 jQuery 实现这一点 谢谢 The HTML div By Anonymous From Minnesota div 我希望它只是 div Anonym
  • JPanel 和 CardLayout 出现 NullPointerException 错误

    我正在为课堂开发酒店管理软件 我的代码遇到了一些问题 此时 我只是尝试将我在单独的类中创建的 JPanel 添加到我的主 gui 中 任何帮助将不胜感激 谢谢 Exception in thread main java lang NullP
  • Python语音识别速度很慢

    我目前正在开发一个智能助手程序 基本上它只是听用户说的话 并据此对代码执行某些操作 直到今天我切换到笔记本电脑时 它都运行良好 该程序不会打印出任何错误 但它也不会打印出我所说的内容 我正在使用Python语音识别 https pypi o
  • 无法使用 PHP 和 Nginx 让 Zorba 在 Windows 7 上运行

    我正在尝试在 Windows 7 计算机上安装 Zorba 的帮助指示 http zorba xquery com doc zorba 2 0 zorba html php windows tutorial html 我已经完成 验证 Zo
  • 将 MSSQL 中除第一个字符和空格之外的字符串的所有字符替换为星号

    我想知道是否可以通过函数对 mssql 中的敏感数据进行哈希处理 并为所有字段保留第一个字符 原样 例子 Jon Kirk 名字应提取为 J K 我首先发布了一个递归解决方案 这更快 declare name varchar 20 Jon
  • Django 的 Capistrano

    有谁知道 Django 中 Capistrano Webistrano 的等效版本吗 Fabric http fabfile org是一个基于Python的应用部署系统 它可用于部署 Django 项目
  • git 没有完全退出(退出代码 128)[重复]

    这个问题在这里已经有答案了 我收到这个错误 尝试了所有解决方案如何解决 TortoiseGit 上的 git 未完全退出 退出代码 128 错误 https stackoverflow com questions 9617336 how t
  • Rails 3.1,capybara-webkit,如何在链接内执行javascript?

    我可以在与水豚的链接中执行javascript吗click link next page 该链接如下所示 a href Next Question a 我在 github 的 capybara 上读到 我可以通过单击提交按钮来提交表单 如下
  • OpenCV 中如何知道图像是否为 RGB?

    我使用 OpenCV 库用 C 编写了一个程序 该程序从网络摄像头录制视频 然后将其分割成帧 我想知道帧是否为 RGB 因为我想访问每个像素的 RGB 属性 用于捕获的编解码器是 CV FOURCC M J P G 如何获取 RGB 色彩空
  • pycharm中的源和资源根是什么?

    我正在开发一个关于 NLP 的项目 我有一个很大的语料库和一些代码 我想在我的项目中将它们分开 但我想知道选择正确的名称是什么 数据与代码就像汇编中的数据段和代码段 或者 来源和资源正如我的一位朋友所坚持的那样 这是正确的术语 我还在 py
  • Android 连接到本地主机

    我试图通过 wamp 服务器将我的 Android 应用程序连接到本地主机 url 但它不起作用 我的目标是获取 json 数据并解析这些数据 对于我的测试 我使用的是设备而不是模拟器 并且我使用 AndroidManifest xml 中
  • 从函数内的 JSON 响应更新全局变量

    我正在尝试从 JSON 响应中获取一些变量并将其显示在自定义表视图中 问题是变量永远不会更新 更多解释是我的代码 func getAddresses let todosEndpoint String my link guard let to
  • 从 Ubuntu 10.10 升级到 12.04 后,multiprocessing.map 和 joblib 仅使用 1 个 cpu

    我有一些完美运行的 python 代码 它使用多处理模块并以 100 的速度加载我机器上的所有 8 个 CPU 当我从 Ubuntu 10 10 升级到 12 04 后 最明显的事情 也许我做了其他什么事情破坏了一切 它停止工作 经过大量调
  • neo4j cypher 单标签与多标签性能

    考虑以下示例 一个基于 Neo4j 的 wiki 其中包含大量文章和更多文章版本 所有编辑的历史记录 使用多个标签来标识每个节点有多大区别 article Article Public article Article Version 然后查
  • 使用CTE简化SQL语句

    我有一个如下查询 SELECT A a A b B c CASE WHEN THEN ELSE END AS CalculatedValue B d FROM dbo TableA A INNER JOIN dbo TableB B ON
  • 在 Django 表单字段之间显示一些自由文本

    我有一个如下所示的表格 class MyForm Form personal data firstname CharField lastname CharField education data university CharField m
  • 如何检查 dynamodb 中的字符串集中是否存在字符串

    我在表中的每个项目中都设置了一个字符串 例如 Title Book 101 Title ISBN 111 1111111111 Authors Author 1 Price 2 Dimensions 8 5 x 11 0 x 0 5 Pag
  • 如何处理“inspect.getsource”的限制 - 或者如何仅获取函数的源?

    我一直在玩inspectPython 标准库中的模块 下面的例子工作得很好 假设inspect已导入 def foo x y return x y print inspect getsource foo 将打印def foo x y n r