python中MetaClass的一些用法
元类在很多编程语言中都有这样的概念,我们都知道,类可以创建对象,类本身也是对象,既然是对象,那么它肯定也是被创造出来的,元类就专门用来创造类对象,于是,这就给我们提供了一种操纵或者监听类的能力。
平时我们创建一个类,使用的是这种方式:
class MyClass(object):
def method(self):
return 1
instance1 = MyClass()
print(instance1.method())
如果把类也看成一个对象,利用元类,我们这样创建一个类:
def method(self):
return 1
klass = type('MyClass', (object,), {'method': method})
instance1 = klass()
print(instance1.method())
如果从写法上看,没什么太大的区别,MetaClass真正有用的地方是,我们可以自定义元类,接下来我们看一段代码:
class RevealingMeta(type):
def __new__(mcs, name, bases, namespace, **kwargs):
print(mcs, "__new__ called")
return super().__new__(mcs, name, bases, namespace)
@classmethod
def __prepare__(metacls, name, bases, **kwargs):
print(metacls, "__prepare__ called")
return super().__prepare__(name, bases, **kwargs)
def __init__(cls, name, bases, namespace, **kwargs):
print(cls, "__init__ called")
super().__init__(name, bases, namespace)
def __call__(cls, *args, **kwargs):
print(cls, "__call__ called")
return super().__call__(*args, **kwargs)
上边的代码可以算是固定写法了,这其中比较重要的概念是这4个方法的调用时机:
__new__当某个类被创建的时候会调用__prepare__在创建类的时候,可以传入额外的字典class Klass(metaclass=Metaclass, extra="value"):,这个方法就是用来创建接收dict的,所以这个方法会在__new__前边调用__init__这个方法算是对__new__的一些补充__call__这个方法会在类被创建的时候调用
我们就利用上边代码创建出来的元类,创建一个类:
class RevealingMeta(type):
def __new__(mcs, name, bases, namespace, **kwargs):
print(mcs, "__new__ called")
return super().__new__(mcs, name, bases, namespace)
@classmethod
def __prepare__(metacls, name, bases, **kwargs):
print(metacls, "__prepare__ called")
return super().__prepare__(name, bases, **kwargs)
def __init__(cls, name, bases, namespace, **kwargs):
print(cls, "__init__ called")
super().__init__(name, bases, namespace)
def __call__(cls, *args, **kwargs):
print(cls, "__call__ called")
return super().__call__(*args, **kwargs)
class RevealingClass(metaclass=RevealingMeta):
def __new__(cls, *args, **kwargs):
print(cls, "__new__ called")
return super().__new__(cls)
def __init__(self):
print(self, "__init__ called")
super().__init__()
如果这时候直接执行代码,会打印出:
<class '__main__.RevealingMeta'> __prepare__ called
<class '__main__.RevealingMeta'> __new__ called
<class '__main__.RevealingClass'> __init__ called
<class '__main__.RevealingClass'> __call__ called
这说明,只要创建了类就会调用上边的方法,这些方法的调用跟实例的创建没有关系,接下来执行:
instance12 = RevealingClass()
在上边打印的后边,会打印出:
<class '__main__.RevealingClass'> __new__ called
<__main__.RevealingClass object at 0x104032048> __init__ called
这就是元类的基本用法了,它一般会用在很多的framework中,但也容易出错,我们可以为某个类随意指定元类,如果该元类没有实现这些方法,就有可能会出现崩溃。
python中MetaClass的一些用法的更多相关文章
- Python中 sys.argv[]的用法
Python中 sys.argv[]的用法 因为是看书自学的python,开始后不久就遇到了这个引入的模块函数,且一直在IDLE上编辑了后运行,试图从结果发现它的用途,然而结果一直都是没结果,也在网上 ...
- 31 Python中 sys.argv[]的用法简明解释(转)
Python中 sys.argv[]的用法简明解释 因为是看书自学的python,开始后不久就遇到了这个引入的模块函数,且一直在IDLE上编辑了后运行,试图从结果发现它的用途,然而结果一直都是没结果, ...
- Python中sorted()方法的用法
Python中sorted()方法的用法 2012-12-24 22:01:14| 分类: Python |字号 订阅 1.先说一下iterable,中文意思是迭代器. Python的帮助文档中对i ...
- Python中int()函数的用法浅析
int()是Python的一个内部函数 Python系统帮助里面是这么说的 >>> help(int) Help on class int in module __builti ...
- Python中 sys.argv的用法简明解释
Python中 sys.argv[]的用法简明解释 sys.argv[]说白了就是一个从程序外部获取参数的桥梁,这个“外部”很关键,所以那些试图从代码来说明它作用的解释一直没看明白.因为我们从外部取得 ...
- Python中metaclass解释
Classes as objects 首先,在认识metaclass之前,你需要认识下python中的class.python中class的奇怪特性借鉴了smalltalk语言.大多数语言中,clas ...
- python中super()的一些用法
在看python高级编程这本书的时候,在讲到super的时候,产生了一些疑惑,super在python中的用法跟其他的语言有一些不一样的地方,在网上找了一些资料,发现基本上很少有文章能把我的疑惑讲明白 ...
- Python中return self的用法
在Python中,有些开源项目中的方法返回结果为self. 对于不熟悉这种用法的读者来说,这无疑使人困扰,本文的目的就是给出这种语法的一个解释,并且给出几个例子. 在Python中,retur ...
- python中Metaclass的理解
今天在学习<python3爬虫开发实战>中看到这样一段代码3 class ProxyMetaclass(type): def __new__(cls, name, bases, attrs ...
随机推荐
- 【DWM1000】 code 解密7一ANCHOR接收到BLINK
接着之前ANCHOR的代码分析,但接收到无线数据,应该执行如下代码 case TA_RX_WAIT_DATA : //already recive a message ...
- linux 文件打包压缩成.tar.gz
tar czvf beian.drcluod.cn.20180509.tar.gz ./beian.drcloud.cn/*
- php 操作json的各种格式
php中操作json的函数 加密:json_encode() ,也就是把数据转成json格式 * 数组转换成json格式时,索引数组得出的结果是不带映射关系,所以都是[]:关联数组是映射,所以最外围是 ...
- JS字符串截取(获取指定字符后面的所有字符内容)
function getCaption(obj){ var index=obj.lastIndexOf("\-"); obj=obj.substring(index ...
- 潭州课堂25班:Ph201805201 爬虫高级 第九课 scrapyd 部署 (课堂笔记)
c rapyd是 scrapy 的部署, 是官方提供的一个爬虫管理工具, 通过他可以非常方便的上传控制爬虫的运行, 安装 : pip install scapyd 他提供了一个json ,web, s ...
- 论文类型Journal、magazin、transaction、letter等的区别
论文类型Journal.magazin.transaction.letter等的区别 http://blog.sina.com.cn/s/blog_5420e0000101a66m.html (201 ...
- php curl数据传输神器
一.curl的概念: curl (Client Url Library Functions) 定义: curl is a command line tool for transfering data ...
- yii2 basic版 MVC 部分
一.model 1.什么是模型 模型是 MVC 模式中的一部分,是表现业务数据.规则和逻辑的对象 可通过继承 yii\base\Model 或它的子类(activeRecord)来定义模型类,基类 y ...
- Tips_方格拼图效果
用原生的javascript实现方格拼图效果 1.新建文件夹 代码如下: 01.html <!DOCTYPE html> <html lang="en"> ...
- HBase 查询导致RegionServer OOM故障复盘
背景:我司作为某运营商公司的技术咨询公司,发现有第三方开发公司在使用HBase 1.1.2 (HDP 2.4.2.258版本)一段时间使用正常后,从某一天开始报OOM,从而导致RegionServer ...