Python元类详解:深入理解面向对象编程

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

Python中的元类是一种特殊的类,用于创建和管理其他类。由于Python中一切皆对象(包括类本身),元类可以被视为"类的类"。它们提供了一种机制,可以在类定义阶段控制类的创建过程并修改其行为。

元类的工作原理

当Python遇到一个类定义时,它会自动使用元类type来创建这个类。整个过程如下:

class MyClass:
    pass

Python内部实际执行的是:

MyClass = type('MyClass', (), {})

其中:

  • 'MyClass' — 类的名称
  • () — 父类元组
  • {} — 类的属性和方法字典

内置元类type负责默认创建Python中的所有类。

创建自定义元类

自定义元类通过继承type并重写其方法来创建:

class MyMeta(type):
    def __new__(cls, name, bases, attrs):
        print(f"正在创建类 {name}")
        attrs['created_by_metaclass'] = True
        return super().__new__(cls, name, bases, attrs)

class MyClass(metaclass=MyMeta):
    pass

print(MyClass.created_by_metaclass)  # True

元类的核心方法

__new__

控制类的创建过程。在__init__之前调用,并返回新创建的类:

class CreationMeta(type):
    def __new__(cls, name, bases, attrs):
        # 在类创建前修改属性
        attrs['class_id'] = id(cls)
        return super().__new__(cls, name, bases, attrs)

__init__

初始化已创建的类:

class InitMeta(type):
    def __init__(cls, name, bases, attrs):
        print(f"正在初始化类 {name}")
        super().__init__(name, bases, attrs)

__call__

定义创建类实例时的行为:

class CallMeta(type):
    def __call__(cls, *args, **kwargs):
        print(f"正在创建 {cls.__name__} 的实例")
        return super().__call__(*args, **kwargs)

实战应用示例

自动转换属性名

class UpperAttrMeta(type):
    def __new__(cls, name, bases, attrs):
        uppercase_attrs = {}
        for attr_name, attr_value in attrs.items():
            if not attr_name.startswith('__'):
                uppercase_attrs[attr_name.upper()] = attr_value
            else:
                uppercase_attrs[attr_name] = attr_value
        return super().__new__(cls, name, bases, uppercase_attrs)

class MyClass(metaclass=UpperAttrMeta):
    attr1 = 'value1'
    attr2 = 'value2'

print(hasattr(MyClass, 'ATTR1'))  # True
print(hasattr(MyClass, 'attr1'))  # False

实现单例模式(Singleton)

class SingletonMeta(type):
    _instances = {}
    
    def __call__(cls, *args, **kwargs):
        if cls not in cls._instances:
            cls._instances[cls] = super().__call__(*args, **kwargs)
        return cls._instances[cls]

class DatabaseConnection(metaclass=SingletonMeta):
    def __init__(self):
        print("正在创建数据库连接")

db1 = DatabaseConnection()
db2 = DatabaseConnection()
print(db1 is db2)  # True

类结构验证

class ValidatedMeta(type):
    def __new__(cls, na                

博客

书籍推荐