如何在元类内部不指定类名引用自身?Python元类问题
Python元类内部无硬编码引用自身的解决方案
问题背景
现有如下Python代码:
class Meta(type): def __new__(cls, name, base, attrs): attrs.update({'name': '', 'email': ''}) return super().__new__(cls, name, base, attrs) def __init__(cls, name, base, attrs): super().__init__(name, base, attrs) cls.__init__ = Meta.func def func(self, *args, **kwargs): setattr(self, 'LOCAL', True) class Man(metaclass=Meta): login = 'user' psw = '12345'
当前代码中cls.__init__ = Meta.func硬编码了元类名称Meta,如果修改元类的名字,这行代码会失效。尝试用cls.__init__ = cls.func时,由于cls指代的是被创建的类(如Man)而非元类Meta,无法实现为对象创建局部变量的需求。需要找到一种无需硬编码元类名称的方式,在元类内部引用自身的方法。
解决方案
可以通过cls.__class__(或type(cls))获取当前类的元类,以此替代硬编码的元类名称:
class Meta(type): def __new__(cls, name, base, attrs): attrs.update({'name': '', 'email': ''}) return super().__new__(cls, name, base, attrs) def __init__(cls, name, base, attrs): super().__init__(name, base, attrs) # 通过cls.__class__获取元类自身,避免硬编码 cls.__init__ = cls.__class__.func def func(self, *args, **kwargs): setattr(self, 'LOCAL', True) class Man(metaclass=Meta): login = 'user' psw = '12345'
原理说明
cls在元类的__init__方法中代表被元类创建的类(比如示例中的Man),而cls.__class__就是该类的元类(即Meta),通过这种方式可以动态获取元类自身,不受元类名称修改的影响。- 测试验证:创建
Man的实例后,实例会自动拥有LOCAL属性并被设为True,完全符合原代码的功能需求。
内容的提问来源于stack exchange,提问作者Pablo Red
相关产品推荐
相关产品推荐

