一文掌握Python 最难知识点:元类

前言

在学习 python 过程中想必大家都会去看源码,看源码的过程中会看到一些元类,但是看起来感觉很吃力看不懂,那是因为我们对元类不够了解。

今天我们就来聊一聊 python 元类,看看元类到底是何方神圣。

2必要知识储备

在讲元类之前我们得先搞清楚类和对象的概念以及类的创建过程,这个至关重要,这取决于我们是否能真正理解和正确使用元类。

类和对象概念

1、类:用来描述具有相同的属性和方法的对象的集合(抽象)

2、对象:类的实体就是对象(具体)传统方式创建类

传统方式创建类

1、代码演示class Demo:    def __init__(self,name):        self.name = name        print("初始化self.name = ",self.name)if __name__ == '__main__'    print("Demo类是由谁创建的:",type(Demo))    print("Demo类的父类:",Demo.__bases__)    cl = Demo("老王")    print("cl实例是由谁创建的:",type(cl))2、输出:Demo类是由谁创建的:<class 'type'>Demo类的父类:(<class 'object'>,)初始化self.name =  老王cl实例是由谁创建的:<class '__main__.Demo'>3、结论:a、类(Demo)是由type创建的b、对象(cl)是由类(Demo)创建的c、基于类(Demo)创建对象(cl),先执行父类(object)的__new__()方法,返回对象(cl)

type 创建类

1、通过上面的例子我们知道,类是由type创建的,那么我们能不能直接通过type来创建类2、type语法type("类名",(继承哪个类,),{"属性名称":"属性值","方法名称key":"方法名称"})3、代码演示demo = type("Demo",(object,),{"name":"老王"})print("类名称:",demo.__name__)print("Demo类是由谁创建的:",type(demo))cl = demo()print("cl实例是由谁创建的:",type(cl))4、输出:类名称:DemoDemo类是由谁创建的:<class 'type'>cl实例是由谁创建的:<class '__main__.Demo'>5、结论a、类(Demo)是由type创建的b、对象(cl)是由类(Demo)创建的c、直接用type创建类和传统方式创建类,效果一模一样

3元类

概念

1、什么是元类:用来创建其他类的类叫元类
2、思考一个问题,我们能不能基于自己定义的类来创建其他的类?

自定义元类并创建类

1、代码演示class Demo1(type):    def __init__(self,*args, **kwargs):        super().__init__(*args, **kwargs)class Demo2(metaclass=Demo1):    def __init__(self,name,age):        self.name = name        self.age = age        print("Demo2类的实例属性:name={}".format(self.name))        print("Demo2类的实例属性:age={}".format(self.age))if __name__ == '__main__':    print("Demo2是由谁创建的:",type(Demo2))    cl = Demo2("老王","20")2、输出:Demo2是由谁创建的:<class '__main__.Demo1'>Demo2类的实例属性:name=老王Demo2类的实例属性:age=203、结论a、类(Demo2)是由Demo1创建的b、可以通过自定义类来创建其他类

4元类经典应用

1、通过元类实现单例模式2、单例模式:在程序执行过程中一个类只实例化一次3、原理:干预类实例化的过程,如果已经实例化了就不再进行实例化class Demo1(type):    def __init__(self,name,bases, attrs):        super().__init__(name,bases, attrs)        self._instance = None    def __call__(self, *args, **kwargs):        #判断是否创建了对象,未创建就调用__new__()方法创建对象,已创建了就不调用__new__()方法,直接返回已创建好的对象        if self._instance is None:            self._instance = self.__new__(self,*args, **kwargs)        #调用自己类(Demo2)的实例化方法        self.__init__(self._instance,*args, **kwargs)        return self._instanceclass Demo2(metaclass=Demo1):    def __init__(self,name,age):        self.name = name        self.age = age        print("Demo2类的实例属性:name={}".format(self.name))        print("Demo2类的实例属性:age={}".format(self.age))if __name__ == '__main__':    print("Demo2是由谁创建的:",type(Demo2))    cl1 = Demo2("老王",20)    cl2 = Demo2("老王",20)    print("cl1实例的内存地址:",id(cl1))    print("cl2实例的内存地址:",id(cl1))    print("cl1 是否是 cl2",cl1 is cl2)4、输出:Demo2是由谁创建的:<class '__main__.Demo1'>Demo2类的实例属性:name=老王Demo2类的实例属性:age=20Demo2类的实例属性:name=老王Demo2类的实例属性:age=20cl1实例的内存地址:1842280993096cl2实例的内存地址:1842280993096cl1 是否是 cl2 True

声明:本站部分文章及图片源自用户投稿,如本站任何资料有侵权请您尽早请联系jinwei@zod.com.cn进行处理,非常感谢!

上一篇 2022年3月18日
下一篇 2022年3月18日

相关推荐