class Meta(type):
def __new__(cls, name, bases, attrs):
new_attrs = {}
for key, value in attrs.items():
if not key.startswith('__'):
def create_getter(key):
def getter(self):
return getattr(self, f'_{key}')
return getter
def create_setter(key):
def setter(self, value):
setattr(self, f'_{key}', value)
return setter
new_attrs[f'get_{key}'] = create_getter(key)
new_attrs[f'set_{key}'] = create_setter(key)
new_attrs.update(attrs)
return super().__new__(cls, name, bases, new_attrs)
class Base(metaclass=Meta):
def __init__(self, **kwargs):
for key, value in kwargs.items():
setattr(self, f'_{key}', value)
class Sub(Base):
class_attr = 'default_value'
def __init__(self, **kwargs):
super().__init__(**kwargs)
if hasattr(self.__class__, 'class_attr'):
setattr(self, '_class_attr', self.__class__.class_attr)
子类初始化过程执行逻辑
- 元类
Meta
的__new__
方法:
- 遍历类属性
attrs
,对于非特殊属性(不以__
开头),为每个属性动态生成get_属性名
和set_属性名
方法。
- 将这些新生成的方法和原有的类属性合并到
new_attrs
字典中。
- 使用
super().__new__
创建新的类对象并返回。
- 父类
Base
的__init__
方法:
- 接受
kwargs
参数,将传入的键值对设置为实例的私有属性(属性名前加_
)。
- 子类
Sub
的__init__
方法:
- 首先调用
super().__init__(**kwargs)
,执行父类的初始化逻辑,处理传入的kwargs
。
- 检查子类是否有
class_attr
类属性,如果有,则将其设置为实例的私有属性_class_attr
。
需要注意的要点
- 元类中的属性处理:
- 要注意避免覆盖原有的特殊方法(如
__init__
等),只处理自定义的普通类属性。
- 继承关系处理:
- 子类初始化时先调用父类的初始化方法,以确保父类的初始化逻辑正常执行,避免破坏继承体系。
- 动态属性生成:
- 在动态生成
getter
和setter
方法时,要注意闭包中变量的作用域问题,确保生成的方法能正确访问和操作对应的实例属性。