- 元类
python中“一切皆对象”。元类,是type类型,就是普通类(平常我们使用class声明的类)的类。换句话说,普通类都是由元类创建的对象。
元类的作用,是为了元编程,是为了创建普通类前,动态调整普通类的结构(修改类的属性和行为)
- 元类里,两个重要的方法:
- new, 创建类,并修改类的结构(属性和行为)。
- init, 初始化创建后的类,修改变量的默认值等(修改的还是类,不是对象)。
class MetaClass(type):
def __new__(cls, name, bases, attrs):
"""cls表示的是:当前类,也就是MetaClass本身"""
print(f"MetaClass.__new__ called with name: {name}, bases: {bases}, attrs: {attrs},cls:{cls}")
attrs['nameFromMeta'] = 'nameFromMeta'
return super().__new__(cls, name, bases, attrs)
def __init__(self, name, bases, attrs):
"""self表示的是:当前类的实例,也就是__new__创建返回的类。本例中就是People.class"""
print(f"MetaClass.__init__ called with name: {name}, bases: {bases}, attrs: {attrs},self:{self}")
self.ageFromMeta = 'ageFromMetaInit'
return super().__init__(name, bases, attrs)
class People(metaclass=MetaClass):
pass
python的元类,就类似于Java的CGLIB等字节码修改工具,不是类似于Java反射(字节码,调整的是类结构; 反射,调整的对象;)
使用示例:
import time
class ProfilerMeta(type):
def __new__(cls, name, bases, attrs):
for key, value in attrs.items():
if callable(value) and not key.startswith("__"):
attrs[key] = cls.profile_method(value)
return super().__new__(cls, name, bases, attrs)
@staticmethod
def profile_method(method):
def wrapper(*args, **kwargs):
start = time.time()
result = method(*args, **kwargs)
print(f"{method.__name__} took {time.time() - start:.4f} seconds")
return result
return wrapper
class ProfilerBase(metaclass=ProfilerMeta):
pass
class DataAnalyzer(ProfilerBase):
def analyze(self, data):
time.sleep(1) # 模拟耗时操作
return sum(data)
# 测试
analyzer = DataAnalyzer()
result = analyzer.analyze([1, 2, 3])
print(f"Result: {result}") # 输出: analyze took 1.0001 seconds, Result: 6