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

Python 2.7中装饰类方法引发unbound method TypeError问题求助

解决类外部装饰classmethod后调用报错的问题

你遇到的这个TypeError是因为装饰后的方法丢失了classmethod的特性,被当成普通的实例方法处理了。让我一步步拆解问题并给出解决办法:

问题根源

在Python 2中,@classmethod装饰的方法是一个descriptor(描述符),当你通过类访问它时,会自动绑定到类本身。但当你把A.demo_method传给装饰器时,你拿到的是一个unbound method对象,装饰器返回的wrapper是普通函数,再通过setattr设回类属性后,这个属性就变成了普通函数,不再具备classmethod的自动绑定逻辑。此时调用A.demo_method(1),Python会默认把它当作实例方法,要求第一个参数是类实例,而你传入的是int类型的1,自然就触发了错误。

解决方案

方案1:装饰后重新包装为classmethod

修改你的装饰器,让它返回的wrapper被classmethod包装,这样就能保留原方法的类绑定特性:

class A(object):
    @classmethod
    def demo_method(cls, a):
        print(a)

def decorator(function):
    from functools import wraps
    @wraps(function)
    def wrapper(*args, **kwargs):
        return_value = function(*args, **kwargs)
        return return_value
    # 将wrapper转换为classmethod,恢复类绑定逻辑
    return classmethod(wrapper)

setattr(A, 'demo_method', decorator(A.demo_method))
A.demo_method(1)  # 现在正常输出1

方案2:先提取原始函数再装饰

另一种方式是先取出classmethod底层的原始函数,装饰后再重新包装成classmethod:

class A(object):
    @classmethod
    def demo_method(cls, a):
        print(a)

def decorator(function):
    from functools import wraps
    @wraps(function)
    def wrapper(*args, **kwargs):
        return_value = function(*args, **kwargs)
        return return_value
    return wrapper

# 取出classmethod的原始函数,装饰后重新包装
original_func = A.demo_method.__func__
setattr(A, 'demo_method', classmethod(decorator(original_func)))
A.demo_method(1)  # 同样正常输出1

验证效果

运行修改后的代码,你会发现demo_method可以正常接收参数并打印,不再抛出TypeError。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.13 08:56:32