博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python_面向对象高级——元类
阅读量:3973 次
发布时间:2019-05-24

本文共 2635 字,大约阅读时间需要 8 分钟。

文章目录

一、引入

一切都源自于一句话:一切皆为对象

二、什么是元类

元类就是用来实例化产生类的类

关系:元类—实例化---->类(People)—实例化---->对象(obj)

class People:    def __init__(self,name,age):        self.name=name        self.age=age    def say(self):        print('%s:%s' %(self.name,self.name))

如何得到对象

obj=调用类()
obj=People(‘egon’,18)
print(type(obj))
如果说类也是对象
People=调用类(。。。)

查看内置的元类:1、type是内置的元类2、我们用class关键字定义的所有的类以及内置的类都是由元类type实例化产生print(type(People))print(type(int))

三、class机制剖析

class关键字创造类People的步骤

类有三大特征:# 1、类名class_name="People"# 2、类的基类class_bases=(object,)# 3、执行类体代码拿到类的名称空间class_dic={
}class_body="""def __init__(self,name,age): self.name=name self.age=agedef say(self): print('%s:%s' %(self.name,self.name))"""exec(class_body,{
},class_dic)# print(class_dic)# 4、调用元类People=type(class_name,class_bases,class_dic)

四、如何自定制类

class Mymeta(type): # 只有继承了type类的类才是元类    #            空对象,"People",(),{...}    def __init__(self,x,y,z):        print('run22222222222....')        print(self)        # print(x)        # print(y)        # print(z)        # print(y)        # if not x.istitle():        #     raise NameError('类名的首字母必须大写啊!!!')    #          当前所在的类,调用类时所传入的参数    def __new__(cls, *args, **kwargs):        # 造Mymeta的对象        print('run1111111111.....')        # print(cls,args,kwargs)        # return super().__new__(cls,*args, **kwargs)        return type.__new__(cls,*args, **kwargs)# People=Mymeta("People",(object,),{...})
调用Mymeta发生三件事,调用Mymeta就是type.__call__1、先造一个空对象=>People,调用Mymeta类内的__new__方法2、调用Mymeta这个类内的__init__方法,完成初始化对象的操作3、返回初始化好的对象

五、call

class Foo:    def __init__(self,x,y):        self.x=x        self.y=y    #            obj,1,2,3,a=4,b=5,c=6    def __call__(self,*args,**kwargs):        print('===>',args,kwargs)        return 123obj=Foo(111,222)# print(obj) # obj.__str__res=obj(1,2,3,a=4,b=5,c=6) # res=obj.__call__()print(res)
应用:如果想让一个对象可以加括号调用,需要在该对象的类中添加一个方法__call__总结:对象()->类内的__call__类()->自定义元类内的__call__自定义元类()->内置元类__call__

六、自定义元类控制类的调用=》类的对象的产生

class Mymeta(type): # 只有继承了type类的类才是元类    def __call__(self, *args, **kwargs):        # 1、Mymeta.__call__函数内会先调用People内的__new__        people_obj=self.__new__(self)        # 2、Mymeta.__call__函数内会调用People内的__init__        self.__init__(people_obj,*args, **kwargs)        # print('people对象的属性:',people_obj.__dict__)        people_obj.__dict__['xxxxx']=11111        # 3、Mymeta.__call__函数内会返回一个初始化好的对象        return people_obj  class People(metaclass=Mymeta):    def __init__(self,name,age):        self.name=name        self.age=age    def say(self):        print('%s:%s' %(self.name,self.name))    def __new__(cls, *args, **kwargs):        # 产生真正的对象        return object.__new__(cls)

转载地址:http://ybxki.baihongyu.com/

你可能感兴趣的文章
python logging现学现用 – TimedRotatingFileHandler使用方法
查看>>
Django开发中整合新浪微博API
查看>>
python logging
查看>>
一个改进的logger类
查看>>
python 获取当前位置所在的函数名和行号
查看>>
python的logging库中TimedRotatingFileHandler类问题
查看>>
2012年7月编程语言排行榜:Objective-C超越C++
查看>>
J2EE快速开发框架Wabacus 3.4发布,开发效率提高5倍以上
查看>>
用Xmanager连接linux服务器
查看>>
集成问题
查看>>
HashCode的作用
查看>>
Linux服务器上安装tomcat
查看>>
crontab举例
查看>>
Django request 信息
查看>>
长连接与短连接
查看>>
ztree实例
查看>>
python str的一些方法
查看>>
Comet技术
查看>>
Python 中两个字典(dict)合并
查看>>
python 字符串和时间转换
查看>>