类装饰器导致跨模块导入时类变为NoneType的原因分析
为什么类装饰器会导致导入的类变成NoneType?
这个问题的根源很清晰:你的register装饰器没有返回被装饰的类对象。当Python使用装饰器修饰类(或函数)时,装饰器的返回值会直接替换原来的类/函数。你的装饰器只完成了注册类到my_dict的操作,但没有返回传入的cls,所以Python会默认返回None,这就导致MyClass最终被替换成了None。
具体分析你的代码
看你定义的register函数:
def register(cls): name = cls.__name__ my_dict[name] = cls
这个函数没有显式的return语句,所以Python会自动返回None。当你用@register装饰MyClass时,Python实际上执行了等价于以下的代码:
MyClass = register(MyClass)
因为register(MyClass)返回None,所以MyClass变量就被赋值为None——这就是为什么在my_main.py中导入MyClass后,打印type(MyClass)会显示NoneType。
解决方法
只需要修改register装饰器,让它在完成注册操作后返回传入的类即可:
my_dict = dict() def register(cls): name = cls.__name__ my_dict[name] = cls return cls # 关键:返回被装饰的类,保持类对象不变 @register class MyClass: def my_method(self): print("running class method") print("my_dict: ", my_dict)
修改后,装饰器完成注册后将原类返回,MyClass仍然是原来的类对象。此时在my_main.py中导入并打印type(MyClass),会输出<class 'my_class.MyClass'>,完全正常。
内容的提问来源于stack exchange,提问作者Fabs
相关产品推荐
相关产品推荐

