python-元类
python中一切皆对象,类的实例是对象,实例的类型是类,类的类型是元类(type)。
class关键字定义的类本身也是一个对象,负责产生该对象的类称为元类,内置的元类为type。
除了用class定义类,也可以用type动态的创建类,传递类名、基类、类的名称空间即可创建一个类。
class A:
pass
print(type(A), type(A())) # <class 'type'> <class '__main__.A'>
B = type('B', (), {'x':1})
b = B()
print(b.x)
def fun(self):
print(self.name)
# 类名:str, 基类:tuple, 名称空间:dict
C = type('B', (A,), {'name':'C', 'fun':fun})
print(C.name)
c = C()
c.fun()
自定义元类
默认情况下所有类的元类是type,可以基础type自定义元类
class Mymeta(type):
def __init__(self, class_name, class_basses, class_dic):
super(Mymeta, self).__init__(class_name, class_basses, class_dic)
if not class_name.istitle():
raise TypeError("类名首字母要大写")
if '__doc__' not in class_dic or len(class_dic['__doc__'].strip())==0:
raise TypeError("类中要有注释")
try:
class A(metaclass=Mymeta):
pass
except Exception as e:
print(e) # 类中要有注释
try:
class b(metaclass=Mymeta):
pass
except Exception as e:
print(e) # 类名首字母要大写
__new__
创建对象时,首先调用new方法创建一个空对象并返回,然后指向init方法进行初始化,new是一个类方法
class Mymeta(type):
def __init__(self, class_name, class_basses, class_dic):
super(Mymeta, self).__init__(class_name, class_basses, class_dic)
def __new__(cls, *args, **kwargs):
print("__new__")
print(cls)
print(args)
print(kwargs)
return super().__new__(cls, *args, **kwargs)
class A(metaclass=Mymeta):
pass
a = A()
# __new__
# <class '__main__.Mymeta'>
# ('A', (), {'__module__': '__main__', '__qualname__': 'A'})
# {}
__call__方法
如果类中定义了call方法,那么类的对象就是一个callable对象。
类是元类的对象,那么在创建类的对象时会调用元类的call方法。
class Mymeta(type):
def __init__(self, class_name, class_basses, class_dic):
print("__init__")
super(Mymeta, self).__init__(class_name, class_basses, class_dic)
def __new__(cls, *args, **kwargs):
print("__new__")
print(cls)
print(args)
print(kwargs)
return super().__new__(cls, *args, **kwargs)
def __call__(self, *args, **kwds):
print("__call__")
print(self)
return super().__call__(*args, **kwds)
class A(metaclass=Mymeta):
pass
print('create a object')
a = A()
"""
__new__
<class '__main__.Mymeta'>
('A', (), {'__module__': '__main__', '__qualname__': 'A'})
{}
__init__
create a object
__call__
<class '__main__.A'>
"""
在定义类的时候就会调用元类的__new和__init方法,而对象的产生是调用元类的__call__方法
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异