找回密码
 会员注册
查看: 18|回复: 0

python高级之元类

[复制链接]

2万

主题

0

回帖

6万

积分

超级版主

积分
69864
发表于 2024-9-10 05:59:46 | 显示全部楼层 |阅读模式
python高级之元类一、Type创建类1、传统方式创建类2、非传统方式二、元类三、总结一、Type创建类classA(object):def__init__(self,name):self.name=namedef__new__(cls,*args,**kwargs):data=object.__new__(cls)returndata12345678'运行运行根据类创建对象obj=A(‘kobe’)1、执行类的new方法,创建对象(空对象),【构造方法】{}2、执行类的init方法,初始化对象,【初始化方法】{‘name’:‘kobe’}对象是基于类创建出来的;问题:类是由谁创建的?类默认是由type创建的1、传统方式创建类classA(object):v1=123deffunc(self):return666print(A) #12345678'运行运行2、非传统方式类名继承类成员A1=type('A',(object,),{"v1":123,"func":lambdaself:666})print(A1)##根据类创建对象obj1=A1() #print(obj1)#调用对象中的func方法print(obj1.func())#66612345678910'运行运行类默认由type创建,怎么让一个类的创建改为其他的东西呢?元类。二、元类元类:指定类由谁来创建1、Foo类由MyType创建,代码如下classMyType(type):pass#Foo类由MyType创建classFoo(object,metaclass=MyType):pass1234567'运行运行2、假设Foo是一个对象,它是由MyType类创建。classMyType(type):def__init__(self,*args,**kwargs):print('init')super().__init__(*args,**kwargs)def__new__(cls,*args,**kwargs):#创建类print('new')new_cls=super().__new__(cls,*args,**kwargs)print(new_cls)returnnew_cls#假设Foo是一个对象,由MyType类创建。classFoo(object,metaclass=MyType):pass1234567891011121314151617'运行运行执行结果newinit1233、类加括号得到的是对象,执行的是__init__()和__new__()方法,对象加括号执行__call__()方法classF1(object):def__init__(self):print('init')#def__new__(cls,*args,**kwargs):#print('new')def__call__(self,*args,**kwargs):print(111)#类加括号得到的是对象,执行的是__init__和__new__方法obj=F1()#对象加括号执行call方法obj()12345678910111213141516'运行运行执行结果init111124、假设Foo是一个对象,由MyType创建。Foo类其实是MyType的一个对象。Foo()加括号执行的是——》MyType类中的__call__()方法__call__()方法实现的功能是:1、调用自己那个类的__new__方法创建对象empty_object=self.__new__(self)2、调用你自己那个类__init__方法去初始化对象self.__init__(empty_object,*args,**kwargs)3、将创建的对象返回:returnempty_objectclassMyType(type):def__init__(self,*args,**kwargs):print('init')super().__init__(*args,**kwargs)def__new__(cls,*args,**kwargs):#创建类print('new')new_cls=super().__new__(cls,*args,**kwargs)print(new_cls)returnnew_clsdef__call__(self,*args,**kwargs):#1、调用自己哪个类的__new__方法创建对象empty_object=self.__new__(self)#2、调用你自己那个类__init__方法去初始化self.__init__(empty_object,*args,**kwargs)returnempty_object#假设Foo是一个对象,由MyType创建。#Foo类其实是MyType的一个对象。#Foo()——》MyType对象()classFoo(object,metaclass=MyType):def__init__(self,name):self.name=namev1=Foo('666')print(v1)print(v1.name)12345678910111213141516171819202122232425262728293031323334'运行运行三、总结1、当我们不写MyType类时,Type中已经帮我们定义好了__init____new____call__方法了当我定义了MyType类时,__init____new____call__方法是我们自己定义的2、这就是为什么实例化对象的时候,先去创建对象再去初始化对象,Type类中已经实现了先__new__()再__init__()3、代码从上到下执行,当执行到classFoo(object,metaclass=MyType)时先创建这个类,去MyType中的__new__()创建方法__init__()实例化方法,类在内存中创建好了,但是MyType中的__call__()方法是不执行的,因为类后面没有加括号如果类后面加了括号Foo(),会执行MyType的__call__()方法4、如果自己定义的类中实现了__call__方法,此时是不会执行的,因为Foo是MyType创建出来的5、如果要执行Foo类的__call__方法,需要实例化Foo类的对象v1,然后v1加括号
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 会员注册

本版积分规则

QQ|手机版|心飞设计-版权所有:微度网络信息技术服务中心 ( 鲁ICP备17032091号-12 )|网站地图

GMT+8, 2025-1-7 06:40 , Processed in 0.442850 second(s), 25 queries .

Powered by Discuz! X3.5

© 2001-2025 Discuz! Team.

快速回复 返回顶部 返回列表