一、先搞懂:Python 一切皆对象

在 Python 中:所有东西都是对象

包括:数字、字符串、列表、函数、甚至类本身

1.1 对象是谁创建的?

普通对象 → 由 类(class) 创建

类(class) → 由 元类(metaclass) 创建

终极层级关系

元类 → 创建类 → 创建对象

对象是类的实例,类是元类的实例

二、type 到底是什么?(核心真相)

绝大多数人不知道:type 是 Python 的内置元类,是所有类的默认创造者。

type 两种用法

  1. type(变量):查看对象类型

  2. type(类名, 父类元组, 属性字典)动态创建类

2.1 常规定义类

class Person:
    pass

2.2 用 type 动态创建类(底层本质)

# type(类名, 继承的父类, 名称空间字典)
Person = type("Person", (), {})

p = Person()
print(type(p))
print(type(Person))

输出结果

<class '__main__.Person'>
<class 'type'>

结论:所有的类,默认都是 type 的实例对象。

三、彻底理清:对象、类、元类关系

class Person:
    pass

p = Person()

# 1. 对象的类型是类
print(type(p))      # Person

# 2. 类的类型是元类 type
print(type(Person)) # type

# 3. type 的类型是自己
print(type(type))   # type

终极关系图

对象 instanceof 类 类 instanceof 元类(type) 元类(type) instanceof 元类(type)

四、动态给类添加属性和方法

利用 type 可以在运行期动态组装类,极其灵活。

def self_intro(self):
    print("我是动态类的方法")

# 动态创建类并绑定属性、方法
Student = type("Student", (), {"name":"小明", "intro":self_intro})

s = Student()
print(s.name)
s.intro()

这就是 Python动态语言的核心特性。

五、自定义元类(重写类的创建过程)

默认元类是 type,我们可以继承 type 自定义元类,干预类的创建过程

元类核心魔法方法 __new__

__new__:用来创建类对象,在类产生之前执行。

自定义元类完整案例

# 自定义元类,继承type
class MyMeta(type):
    # 控制类的创建
    def __new__(cls, name, bases, attrs):
        print("正在创建类:", name)
        # 放行,创建类
        return super().__new__(cls, name, bases, attrs)

# 指定该类使用自定义元类
class Person(metaclass=MyMeta):
    pass

运行结果

正在创建类: Person

可以看到:类在定义阶段就被元类拦截、管控

六、元类实战:强制类必须拥有指定属性

元类最大用途:代码规范校验、强制子类格式、框架约束

需求:所有使用该元类的类,必须包含 name 属性,否则报错

class MyMeta(type):
    def __new__(cls, name, bases, attrs):
        # 校验类是否包含name属性
        if "name" not in attrs:
            raise Exception("自定义错误:类必须包含 name 属性!")
        return super().__new__(cls, name, bases, attrs)

# 合法
class Student(metaclass=MyMeta):
    name = "学生"

# 非法(会报错)
# class Teacher(metaclass=MyMeta):
#     pass

这就是 Django ORM、SQLAlchemy、爬虫框架 的底层原理!

七、元类的执行时机

普通类 __init__:创建对象时执行

元类 __new__定义类的瞬间就执行,无需实例化

八、元类到底用来干什么?(面试标准答案)

元类是类的类,用来创建和控制类

日常开发几乎不用,但是写框架必须用

  1. 强制子类规范(统一属性、统一方法)

  2. 自动注册类、自动映射

  3. 拦截类创建、修改类属性

  4. ORM 数据表字段映射底层实现

名言: 简单项目用面向对象,框架底层用元类

九、全文终极总结

  1. Python 中 对象由类创建,类由元类创建

  2. 默认元类是 type,type 可以动态创建类;

  3. 自定义元类需要 继承 type、重写 __new__

  4. 元类在类定义阶段触发,用于管控类的行为;

  5. 用途:框架底层、代码规范、自动注册、ORM映射。

更多推荐