Python带参数类装饰器报错:TypeError缺少必选参数'type'
问题分析与解决
错误原因
你写的带参数类装饰器结构不对。当用@myDecorator(str)时,Python会先执行myDecorator(str),但你的myDecorator函数要求两个参数cls和type,只传了str,自然会报缺参数的错。
带参数的装饰器必须是三层嵌套结构:
- 最外层函数接收装饰器的参数(比如这里的
type) - 中间层函数接收被装饰的类(
cls) - 最内层返回包装后的类
另外你还有两个逻辑问题:
wrapper类的__init__方法第一个参数用了cls,这是类方法的参数,实例方法应该用self- 统计类变量应该在装饰类的时候完成,而不是实例化时——类变量是类级别的,不需要每次创建实例都重新统计
修正后的代码
def myDecorator(type): # 外层函数接收装饰器参数,返回真正的装饰器 def decorator(cls): # 中间层接收被装饰的类 class wrapper(cls): contaVarClasse = 0 def __init__(self, *args, **kwargs): # 调用原类的__init__方法 super().__init__(*args, **kwargs) # 在装饰阶段统计类变量 for attr_name, value in cls.__dict__.items(): # 排除特殊属性(比如__module__、__doc__这些) if not attr_name.startswith('__') and isinstance(value, type): wrapper.contaVarClasse += 1 return wrapper return decorator @myDecorator(str) class MyClass: countme = "b" notme = 2 def __init__(self): dontcountme = "a" # 这是实例变量,不会被统计 norme = 5 print(MyClass.contaVarClasse) # 输出:1
关键修正点
- 三层嵌套装饰器:外层
myDecorator接收type参数,返回中间的decorator函数,这个函数才接收被装饰的MyClass - 类变量统计时机:在装饰类的时候直接遍历原类的
__dict__,统计符合类型的类变量,结果存在wrapper.contaVarClasse里,避免每次实例化重复计算 - 修正
__init__参数:把cls改成self,并用super()调用原类的构造方法,保证原类的初始化逻辑正常执行 - 过滤特殊属性:遍历
__dict__时排除以__开头的特殊属性,避免统计到系统自带的属性
内容的提问来源于stack exchange,提问作者Maridiama
相关产品推荐
相关产品推荐

