Python开发装饰器时,如何查找方法所属的类?
解决方法:辨别函数/方法并获取所属类
这个问题我之前在写装饰器的时候也碰到过,Python的方法对象其实自带了几个关键属性,能帮我们轻松区分函数和方法,还能拿到方法所属的类。下面直接上可行的实现方案:
实现 getOwner 函数
def getOwner(func): # 处理绑定实例方法(比如 test.method 这种) if hasattr(func, '__self__'): # __self__ 指向调用方法的实例,实例的 __class__ 就是所属类 return func.__self__.__class__ # 处理类方法、静态方法,或者未绑定的类内函数 elif hasattr(func, '__func__') and hasattr(func.__func__, '__qualname__'): # __qualname__ 包含方法的完整路径,比如 "Example.cls_method" parts = func.__func__.__qualname__.split('.') if len(parts) > 1: # 从模块中获取对应的类 from inspect import getmodule module = getmodule(func) return getattr(module, parts[0]) # 普通函数直接返回 None 或者你需要的标识 return None
测试你的示例代码
把 getOwner 加入你的代码后,运行结果就会符合预期:
class Example: def method(self): print("I'm a method") def getOwner(func): if hasattr(func, '__self__'): return func.__self__.__class__ elif hasattr(func, '__func__') and hasattr(func.__func__, '__qualname__'): parts = func.__func__.__qualname__.split('.') if len(parts) > 1: from inspect import getmodule module = getmodule(func) return getattr(module, parts[0]) return None def exampleFunc(func): owner = getOwner(func) print(owner) test = Example() exampleFunc(test.method)
运行后输出:
<class '__main__.Example'>
额外场景的适配
这个实现还能处理其他常见的方法类型:
- 类方法:
class Example: @classmethod def cls_method(cls): pass exampleFunc(Example.cls_method) # 输出 <class '__main__.Example'> - 静态方法:
class Example: @staticmethod def static_method(): pass exampleFunc(Example.static_method) # 输出 <class '__main__.Example'> - 普通函数:
def normal_func(): pass exampleFunc(normal_func) # 输出 None
用 inspect 模块的替代方案
如果你更倾向于用标准库的工具,inspect 模块能更清晰地判断对象类型:
import inspect def getOwner(func): if inspect.ismethod(func): # 绑定方法:如果是类方法,__self__ 就是类本身;如果是实例方法,__self__ 是实例 return func.__self__ if isinstance(func.__self__, type) else func.__self__.__class__ elif inspect.isfunction(func): # 检查是否是类内定义的函数(静态方法或未绑定方法) if hasattr(func, '__qualname__'): parts = func.__qualname__.split('.') if len(parts) > 1: from inspect import getmodule module = getmodule(func) return getattr(module, parts[0]) return None
这个版本逻辑更直观,适合需要更严谨类型判断的场景。
内容的提问来源于stack exchange,提问作者user189728
相关产品推荐
相关产品推荐

