Python 的元类是什么?
我从“类也是对象”这个底层事实讲起,画个关系图,然后落到具体用法上。
🧩 类也是对象,那类的类就是元类¶
Python 里常说“一切皆对象”,这句话没说完:类本身也是对象。
Dog 这个类,它的类型是 type。既然 Dog 是对象,那它肯定也是由某个类实例化出来的,这个“创建类的类”,就是元类。
用图把这几层关系画清楚:
拿 Dog 举例:
-
d = Dog()→d是Dog的实例。 -
Dog类是type的实例。 -
所以
type就是Dog的元类。
⚙️ class 语句的背后:元类在偷偷干活¶
当我们写:
解释器实际干的事大致等于:
type 作为元类,它的 new 和 init 负责:
-
收集类名、基类、类属性字典。
-
创建真正的类对象。
-
返回这个类对象,并绑定到变量
Dog上。
所以元类就是拦截类创建过程的钩子。你可以在这里偷天换日:改类名、加属性、注册到某个中心、强制检查接口,啥都行。
🔧 自定义元类:一个加前缀的例子¶
比如我想让某个包下面所有类的属性,自动加上 my_ 前缀,防御命名冲突。自定义元类这样做:
class PrefixMeta(type):
def __new__(mcs, name, bases, namespace):
# 把所有非内置、非私有属性加上前缀
prefixed = {}
for k, v in namespace.items():
if not k.startswith('__'):
prefixed['my_' + k] = v
else:
prefixed[k] = v
return super().__new__(mcs, name, bases, prefixed)
class User(metaclass=PrefixMeta):
name = 'alice'
age = 30
print(User.my_name) # 'alice'
print(User.my_age) # 30
print(hasattr(User, 'name')) # False