Python装饰器创建类时如何自定义type()返回的类名?
解决Python装饰器生成类的type()名称显示问题
你遇到的问题是因为仅修改了类的__name__和__module__属性,但Python在通过type()显示类信息时,还会参考__qualname__属性——这个属性记录了类的嵌套结构全名,用class语句创建的嵌套类会自动带上嵌套路径,所以需要手动覆盖它。
修复方案1:补充修改__qualname__
直接在装饰器中同时设置类的__name__、__qualname__和__module__属性:
class Animal: pass def linnean_name(genus, species): def _linnean_name(fn): class _Animal(Animal): binomial_name = (genus, species) def converse(self): fn() # 同步设置三个核心属性 _Animal.__name__ = fn.__name__ _Animal.__qualname__ = fn.__name__ _Animal.__module__ = fn.__module__ return _Animal return _linnean_name @linnean_name('Vombatus', 'ursinus') def Wombat(): print("Hello, I am a wombat.") sheila = Wombat() print(type(sheila)) # 输出 <class '__main__.Wombat'>
修复方案2:动态创建类(更彻底)
使用types.new_class直接生成目标类,避免嵌套结构带来的名称问题,这种方式可以直接指定类名,无需后续修改属性:
import types class Animal: pass def linnean_name(genus, species): def _linnean_name(fn): # 定义类的属性和方法 class_namespace = { 'binomial_name': (genus, species), 'converse': lambda self: fn() } # 动态创建类,指定类名、基类和命名空间 new_class = types.new_class( fn.__name__, (Animal,), {}, lambda ns: ns.update(class_namespace) ) new_class.__module__ = fn.__module__ return new_class return _linnean_name @linnean_name('Vombatus', 'ursinus') def Wombat(): print("Hello, I am a wombat.") sheila = Wombat() print(type(sheila)) # 输出 <class '__main__.Wombat'>
内容的提问来源于stack exchange,提问作者Marnanel Thurman
相关产品推荐
相关产品推荐

