博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python进阶-面向对象编程六:元类
阅读量:6370 次
发布时间:2019-06-23

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

什么是元类

# typer===>produce class===>produce obj# type称谓元类,是所有类的类,利用type控制类的行为

模拟class关键字创建类的过程:类被创建的2种方法

# 模拟class关键字创建类的过程# 创建类的两种方式# 方式一:class Foo:    def func(self):        print('from func')# 方式二:x = 1def func(self):    print('from func')Foo=type('Foo',(object,),{'func':func,'x':1})# 创建类的两种方式# 方式一:class Foo:    x=1    def run(self):        passprint(type(Foo))# 
# 方式二:class_name="Bar"def Run(self): print("%s is running"%self.name)bases=(object,)class_dic={ "x":1, "run":Run}Bar=type(class_name,bases,class_dic)print(Bar)print(type(Bar))print(type("123"))print(type(123))# 运行结果:#
#
#
#

 

自定制一个元类,让它必需具有注释

# 元类,我们重定义的元类如果不写注释就暴错class Mymeta(type):    def __init__(self,class_name,class_bases,class_dic):        for key in class_dic:            if not callable(class_dic[key]):continue            if not class_dic[key].__doc__:                raise TypeError("all the func must be notes")class Foo(metaclass=Mymeta):    x=1    def run(self):        '所有函数必须写注释'        print("class Foo")Foo().run()

  

创建元类的具体过程

# 一切皆对象,类也是对象,元类就是类的类# type()内建函数可以创建类class C(object):    passc=C()print(c)print(C)# <__main__.C object at 0x10d41fc18># 
# type(类名, 父类的元组(可以为空), 属性的字典)def printinfo(self): print("%s age %s"%(self.name,self.age))S = type("Student",(object,),{"name":'adamanter',"age":24,"printinfo":printinfo})print(type(S))s=S()print(type(s))s.printinfo()#
#
# adamanter age 24# 函数type实际上是一个元类,元类就是用来创建类的"模板"。# 我们可以通过类"模板"创建实例对象,同样,也可以使用元类"模板"来创建类对象;# 也就是说,元类就是类的类.# 创建类的过程是,__new__,__init__,创建出类来进行实例化的过程是__call__# python2# 在创建一个类的时候,可以设置"__metaclass__"属性来指定元类。# __metaclass__ = QueueMetaclass# 属性后面对应的就是创建类的代码,可以是函数,也可以是一个类# 元类的查找就是根据__metaclass__属性一层层向父类查找,如果找不到就用type创建类对象# python3:# class Hello(matacalss=QueueMetaclass):# passdef queueMeta(name, bases, attrs): attrs['InQueue'] = lambda self, value: self.append(value) def deQueue(self): if len(self) > 0: return self.pop(0) attrs['DeQueue'] = deQueue # 直接调用type内建函数 return type(name, bases, attrs)# 元类从`type`类型派生class QueueMetaclass(type): def __new__(cls, name, bases, attrs): cls.name = name cls.bases = bases attrs['InQueue'] = lambda self, value: self.append(value) print("cls",cls) print("name",cls.name) print("bases",cls.bases) def deQueue(self): if len(self) > 0: return self.pop(0) attrs['DeQueue'] = deQueue # 直接调用type内建函数 # return type(name, bases, attrs) # 通过父类的__new__方法 return type.__new__(cls, name, bases, attrs)class MyQueue(metaclass=QueueMetaclass): # 设置metaclass属性,可以使用一个函数,也可以使用一个类,只要是可以创建类的代码 # __metaclass__ = queueMeta passq = MyQueue()print(q)# 拦截类的创建# 根据"__metaclass__"对应的代码修改类# 返回修改之后的类class MyMetaclass(type): def __new__(meta, name, bases, attrs): print('-----------------------------------') print("Allocating memory for class:", name) print(meta) print(bases) print(attrs) return super(MyMetaclass, meta).__new__(meta, name, bases, attrs) def __init__(cls, name, bases, attrs): print('-----------------------------------') print("Initializing class:", name) print(cls) print(bases) print(attrs) super(MyMetaclass, cls).__init__(name, bases, attrs)class MyClass(metaclass=MyMetaclass): def foo(self, param): passmyclass = MyClass()# -----------------------------------# Allocating memory for class MyClass#
# ()# {'foo':
, '__module__': '__main__', '__qualname__': 'MyClass'}# -----------------------------------# Initializing class MyClass#
# ()# {'foo':
, '__module__': '__main__', '__qualname__': 'MyClass'}

  

 

转载于:https://www.cnblogs.com/adamans/articles/7517585.html

你可能感兴趣的文章
我的友情链接
查看>>
JSP九大内置对象
查看>>
解决Mysql字符编码问题
查看>>
Mac OS 显示隐藏文件
查看>>
Linode Center OS 6.5(x64) 用Nginx 反向代理多个Tomcat 负载均衡。
查看>>
Eclipse4.X版本安装fatjar插件(luna mars 版本均可用)
查看>>
conv与convn的区别
查看>>
Jedis使用总结
查看>>
【Spring Boot】4.日志
查看>>
rails mysql2中文编码及innodb前缀索引长度问题
查看>>
几何画板怎样画半圆?
查看>>
antd-mobile使用
查看>>
超实用CAD控件CAD VCL发布v12,支持Embarcadero®RAD Studio 10.2 Tokyo丨附下载
查看>>
让电脑去死吧 ~ python
查看>>
校园网IPV6设置与应用
查看>>
git Your branch is ahead of ... 解决办法
查看>>
Centos 7 JDK、Tomcat9 安装并配置
查看>>
js中void作用
查看>>
MySQL索引背后的数据结构及算法原理
查看>>
PHP FPM源代码反刍品味之六:IO事件机制的封装.
查看>>