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 ...
随机推荐
- STM32——C语言课堂原代码
指针 /* ============================================================================ Name : Hello.c Au ...
- docker -v挂载
docker run -d -p 3306:3306 -v /var/lib/mydata:/var/lib/mysql my_sql docker exec -it mys_sql /bin/ba ...
- ReactNative bug:Application XXX has not bean registered.
故障现象 当react-native init新项目之后运行react-native run -android/ios时手机报错 Application XXX has not bean regist ...
- shell脚本使用技巧7--cat
cat是单词concatenate缩写 echo 'text through stdin' | cat - file.txt 输出:text throgh stdin 和file.txt中的内容: c ...
- Drying [POJ3104] [二分答案]
背景 每件衣服都有一定单位水分,在不适用烘干器的情况下,每件衣服每分钟自然流失1个单位水分,但如果使用了烘干机则每分钟流失K个单位水分,但是遗憾是只有1台烘干机,每台烘干机同时只能烘干1件衣服,请问要 ...
- 2017.07.09【NOIP提高组】模拟赛B组
Summary 今天放假,比赛于是就没有打了,但是看了一下题,发现都挺简单了,不想码~╮(╯▽╰)╭懒虫一条.最后一题居然做过原题.这次比赛让我对并查集“刮目相看”,对贪心感到“前途无量”,觉得树形D ...
- UIAlertController简单使用
UIAlertView 在iOS2 的时候开始使用,在iOS9 的时候被摒弃 NS_CLASS_DEPRECATED_IOS(2_0, 9_0, "UIAlertView is depr ...
- db2性能优化
性能优化概述 DB2 的性能优化可以从三个方面分析:内存,CPU 和 I/O .DB2 性能优化是一件较为复杂的综合性的工作 , 需要对问题的根源作全方位的探索和思考.同时也需要较深厚的数据库管理经验 ...
- Linux之nfs服务
1.二进制安装nfs 2.作为共享存储挂载在三台web的网站根目录下实现,在任意一台web上修改的结果,其余两台都可以看到 [root@localhost ~]# yum install rpcbin ...
- C++加载动态库的顺序
1. where to load dynamic so: (rpath isdetermined and recorded when compiling, it is also used to f ...