You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python获取函数定义文件及对象属性函数父类型(兼容Py2/3)

嘿,我来帮你搞定这个兼容Python 2和3的函数信息获取问题,分两部分给你拆解解决方案,用inspect模块会比直接碰魔术属性更省心,因为它帮我们抹平了两个版本的差异:

1. 获取函数定义的源文件名

最稳妥的方式是用inspect.getsourcefile(),它能直接返回函数定义所在的源文件路径,还能处理内置函数、动态生成函数这类特殊情况(遇到这些情况会返回None或者抛出TypeError,你可以按需捕获)。

示例代码:

import inspect

for i, func in enumerate(list_of_functions):
    try:
        filename = inspect.getsourcefile(func)
    except TypeError:
        # 处理无法获取源文件的场景,比如内置函数
        filename = "N/A"
    # 兼容Py2的字符串格式化(Py2用%,Py3可以用f-string,这里用format兼容两者)
    print("{0}: {1} | 源文件: {2}".format(i, func.__name__, filename))

要是不想依赖inspect,也可以手动兼容两个版本的魔术属性:Python 2里函数的代码对象是func.func_code,Python 3里是func.__code__,然后取co_filename属性就行。不过这种方式碰到内置函数会报错,所以还是优先推荐inspect:

for i, func in enumerate(list_of_functions):
    # 兼容Py2/Py3的代码对象获取
    code_obj = func.func_code if hasattr(func, 'func_code') else func.__code__
    filename = code_obj.co_filename
    print("{0}: {1} | 源文件: {2}".format(i, func.__name__, filename))
2. 获取函数所属父对象的类型

如果函数是某个对象的属性(比如类的实例方法、类方法),核心是判断它是不是绑定方法——两个版本在这里的属性命名不一样,inspect同样能帮我们简化处理:

示例代码:

import inspect

for i, func in enumerate(list_of_functions):
    parent_type = None
    # 先判断是不是绑定方法
    if inspect.ismethod(func):
        # Py2用im_self,Py3用__self__,统一兼容
        instance_or_cls = func.im_self if hasattr(func, 'im_self') else func.__self__
        parent_type = type(instance_or_cls)
        # 要是类方法的话,instance_or_cls本身就是类,type()会返回type,这里直接用原对象更准确
        if parent_type is type:
            parent_type = instance_or_cls
    # 补充:如果是未绑定的类函数(Py3里是普通函数,Py2里是未绑定方法)
    elif hasattr(func, '__qualname__') and '.' in func.__qualname__:
        # __qualname__会带类名,比如MyClass.my_method,这里可以简单解析出类名
        parent_name = func.__qualname__.split('.')[0]
        # 但这种方式需要你能拿到类的全局引用,不如绑定方法的情况直接
        # 所以如果是从对象实例/类上直接取的方法,优先用上面的绑定方法判断
        pass
    print("{0}: {1} | 父对象类型: {2}".format(i, func.__name__, parent_type if parent_type else "无"))

举个实际的例子帮你理解:

class MyClass:
    def my_method(self):
        pass

obj = MyClass()
bound_method = obj.my_method  # 绑定到实例的方法
unbound_func = MyClass.my_method  # Py3是普通函数,Py2是未绑定方法

# 对bound_method,父对象类型是MyClass
# 对unbound_func,Py2里可以通过func.im_class拿到MyClass,Py3里需要靠__qualname__解析

内容的提问来源于stack exchange,提问作者00__00__00

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 08:41:04