Python中如何快速查看包、模块、类或函数的源码?分享一个实用脚本

为啥造轮子:开发或者学习 Python 时,我们可能经常需要查看某个函数或者某个类的文档。 举个例子,之前我自己在使用 requests 时,就经常会想去查看 requests.Session 的源码实现? 但这时候,有没有什么快捷的方法迅速看到源码呢?

之前我有几个办法:

  1. 去 Github 上面搜
  2. 将 requests 源码拷贝在本地
  3. 在 IDE/编辑器 中跳转到函数定义
  4. cd 到 site-packages 目录中去,然后使用编辑器打开

但这些办法都比较麻烦:今天偶然看到 jedi 的使用示例,于是撸了一个「快速跳转到 Python 函数、类、包 定义」的脚本。

https://github.com/cosven/rcfiles/blob/master/bin/mpy-goto-def

使用方法

  1. 请确保机器安装了 Python 3 (版本 >= 3.6 )
  2. 下载脚本
  3. 执行下面命令时,它会自动调用编辑器打开相应文件,并跳转到对应的行( Vim/Emacs 测试 OK )
    ./mpy-goto-def asyncio.wait
    

进阶使用 - 开启自动补全

  1. 将脚本加入 PATH
  2. pip3 install argcomplete
  3. register-python-argcomplete mpy-goto-def >> .bashrc
  4. source .bashrc

开启自动补全后,我们在命令行输入 mpy-goto-def flask.Res 时 按 <tab> 会自动弹出 Response, Request 等候选项。</tab>

~ > mpy-goto-def flask.Re
flask.Redirect                flask.Request_finished
flask.Render_template         flask.Request_started
flask.Render_template_string  flask.Request_tearing_down
flask.Request                 flask.Response

bonus

推荐一个工具:pydoc -> 命令行查看 Python 文档神器


Python中如何快速查看包、模块、类或函数的源码?分享一个实用脚本

17 回复

Performance 方面如何呀?快不快


帖子回复:

这个问题很实用,直接上代码。我平时就用这个脚本来快速定位源码,比在IDE里点来点去快多了。

import inspect
import importlib
import sys

def view_source(target_name):
    """
    查看Python包、模块、类或函数的源代码
    
    参数:
        target_name: 可以是:
            - 模块名 (如 'os.path')
            - 模块中的类/函数 (如 'collections.Counter')
            - 包名 (如 'numpy')
    """
    try:
        # 尝试直接导入
        if '.' in target_name:
            # 处理类似 'module.Class' 或 'module.function' 的情况
            parts = target_name.split('.')
            module_name = parts[0]
            attr_path = parts[1:]
            
            module = importlib.import_module(module_name)
            obj = module
            
            # 逐级获取属性
            for attr in attr_path:
                obj = getattr(obj, attr)
        else:
            # 直接导入模块
            obj = importlib.import_module(target_name)
        
        # 获取源代码
        if inspect.ismodule(obj):
            print(f"=== 模块: {target_name} ===")
            source = inspect.getsource(obj)
        elif inspect.isclass(obj):
            print(f"=== 类: {target_name} ===")
            source = inspect.getsource(obj)
        elif inspect.isfunction(obj) or inspect.ismethod(obj):
            print(f"=== 函数/方法: {target_name} ===")
            source = inspect.getsource(obj)
        else:
            print(f"=== 对象: {target_name} ===")
            source = str(obj)
        
        print(source)
        
    except ImportError as e:
        print(f"导入错误: {e}")
    except AttributeError as e:
        print(f"属性错误: {e}")
    except Exception as e:
        print(f"其他错误: {e}")

# 使用示例
if __name__ == "__main__":
    # 示例1: 查看模块
    view_source('collections')
    
    # 示例2: 查看模块中的类
    view_source('collections.Counter')
    
    # 示例3: 查看模块中的函数
    view_source('os.path.join')

使用说明:

  1. 基本用法:直接调用 view_source('模块名')view_source('模块.类名')
  2. 查看内置模块:比如 view_source('collections')
  3. 查看第三方包:确保已经安装,比如 view_source('numpy.array')
  4. 查看函数:比如 view_source('os.path.join')

核心原理:

  • importlib.import_module() 动态导入模块
  • inspect.getsource() 获取源代码
  • 支持链式属性访问(比如 module.Class.method

注意点:

  • 有些内置模块(C扩展)看不到源码,会显示 <built-in> 之类的信息
  • 对于大型模块,输出可能很长,建议配合分页工具使用

一句话总结: 这个脚本能快速定位Python对象的源码,调试和学习时特别有用。

G 感觉大多数情况 help()就够了

写 python 都不要 IDE 的吗

vim 自动补全的那个 ,gd 就好吧…

vim/Emacs 等编辑器后端用的应该都是 jedi,这个命令也主要是基于 jedi 来做的

我在 macbook pro 2017(8G) 上测试了几个:一般 0.3s 可以查出来,如果输入的类或者函数真的不存在,一般需要 0.5s 。感觉算一般吧,能用的级别 🤔

ummm,现代的编辑器都很强了,感觉 IDE 确实是个可选项,不过这个主要还是看个人习惯。

嗯,是的。如果是在编辑器里面的话,是可以直接查看函数定义。比如 vim,快捷键 gd 就可以 goto-definition。

这个工具主要是提供了一种在命令行直接查看函数 /类定义的可能性。

试了下 help,它可以在 REPL 环境中使用,和 pydoc 提供的功能似乎是一样的

(这个我之前倒是没怎么了解过 ~

pycharm Ctrl+左键单击 自动跳转

如果用 Pycharm 的话在对应函数上按 Ctrl + Q,有惊喜

pycharm 鼠标中键按一下。。。就一下。。。

#10 居然还有这种功能

ctrl+p 参数列表,ctrl+q api 文档,ctrl+b 跳转源码(等同 ctrl+鼠标左键点)

为啥造轮子?
在 Pycharm 里,光标点在函数或对象上面,然后按需求打开 view 菜单从上面 2-5 项。快捷键就显示在右侧。

回到顶部