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__方法

posted @   店里最会撒谎白玉汤  阅读(26)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
· 从HTTP原因短语缺失研究HTTP/2和HTTP/3的设计差异
点击右上角即可分享
微信分享提示