python黑魔法之metaclass
最近了解了一下python的metaclass,在学习的过程中,把自己对metaclass的理解写出来和大家分享。
首先, metaclass 中文叫元类,这个元类怎么来理解呢。我们知道,在Python中,一切都是对象。我们定义一个类,然后实例化,得到了一个类的实例对象。我们可以把类理解成创建实例对象的模板。其实,这个模板,也就是类本身,也是一个对象。既然类也是对象,那么我们就可以对他进行很多操作。比如,把类作为函数的参数,创建类的引用等等。那么创建类的模板,就是元类。
在Python中,我们很早就接触了一个函数 type,用来返回对象的类型。比如
In [1]: print(type(1))
<type 'int'>
In [2]: print(type(""))
<type 'str'>
In [3]: def foo():pass
In [4]: print (type(foo))
<type 'function'>
In [5]: class Foo():pass
In [6]: print(type(Foo()))
<type 'instance'>
In [7]: print(type(Foo))
<type 'classobj'>
其实 type函数还有另外一个用处,那就是用来创建类,用法就是
type(classname,(superclassname,),{attrs}),我们来看一下:
MyClass = type("MyClass",(),{})
其实等效于
class MyClass():
pass
我们说过,metaclass是创建类的类,所以,type就是一个metaclass。我们来验证一下
In [23]: age.__class__
Out[23]: int
In [24]: name.__class__
Out[24]: str
In [25]: MyClass().__class__
Out[25]: __main__.MyClass
In [26]: MyClass().__class__.__class__
Out[26]: type
In [29]: age.__class__.__class__
Out[29]: type
In [30]: name.__class__.__class__
Out[30]: type
type是内置的metaclass,我们也可以自己定义自己的元类。在定义类的时候,定义 __metaclass__属性,这种情况下,Python就会使用metaclass 来创建类。具体模式如下:
在创建类时,Python会寻找有没有定义__metaclass__,如果有,就用定义好的metaclass来创建类。
如果在当前类找不到 __metaclass__,Python会在当前模块下寻找__metaclass__
如果还是找不到,Python会寻找当前类第一个父类的__metaclass__,直到最后的内建函数type()
那么__metaclass__定义到底是什么呢?
是任何能够创建类的,比如type或者type的子类
所以metaclass的目的在类创建的时候自动的修改类,举个例子,我们想把一个类里所有的属性前面都加一个my_前缀,使用metaclass的方式就比较简单
class MyAttrMetaclass(type):
def __new__(cls, clsname, bases,dct):
my_attr = {}
for name, val in dct.items():
if not name.startswith('__'):
my_attr["my_"+name] = val
else:
my_attr[name] = val
return type.__new__(cls, clsname, bases, my_attr) class Foo():
__metaclass__= MyAttrMetaclass
test_age = 1
test_name = "test" print(hasattr(Foo,"test_age"))
False
print(hasattr(Foo,"my_test_age"))
True
可以看到通过元类的方式,我们的类Foo的属性被修改了。
最后一个问题就是我们在什么情况下会用到metaclass呢?
常见的例子有Django ORM 的Model类,
我们定义一个Person类集成Model
class Person(Model):
name = models.CharField(max_length=30)
age = models.IntegerField() p = person(name="haha",age="31")
p.age 返回的是int 而不是IntegerField(),这就是因为在Model中使用的metaclass动态修改类
本文总结了黑魔法metaclass的定义,用法,主要参考了http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python
python黑魔法之metaclass的更多相关文章
- Python 黑魔法 --- 描述器(descriptor)
Python 黑魔法---描述器(descriptor) Python黑魔法,前面已经介绍了两个魔法,装饰器和迭代器,通常还有个生成器.生成器固然也是一个很优雅的魔法.生成器更像是函数的行为.而连接类 ...
- (转)Python黑魔法 --- 异步IO( asyncio) 协程
转自:http://www.jianshu.com/p/b5e347b3a17c?from=timeline Python黑魔法 --- 异步IO( asyncio) 协程 作者 人世间 关注 201 ...
- python 黑魔法 ---上下文管理器(contextor)
所谓上下文 计算机上下文(Context)对于我而言,一直是一个很抽象的名词.就像形而上一样,经常听见有人说,但是无法和现实认知世界相结合. 最直观的上下文,莫过于小学的语文课,经常会问联系上下文,推 ...
- Python 黑魔法(持续收录)
Python 黑魔法(持续收录) zip 对矩阵进行转置 a = [[1, 2, 3], [4, 5, 6]] print(list(map(list, zip(*a)))) zip 反转字典 a = ...
- python 黑魔法收集--已结
awesome python 中文大全 Fabric , pip, virtualenv 内建函数好文 awesome python 奇技淫巧 一句话求阶乘 from functools import ...
- python 中的metaclass和baseclasses
提前说明: class object 指VM中的class 对象,因为python一切对象,class在VM也是一个对象,需要区分class对象和 class实例对象. class instance ...
- python中的metaclass
首先看下面的代码: # coding: utf-8 class Test(object): pass print Test.__class__ # type print Test.__base__ # ...
- python 元类——metaclass
from stack overflow:http://stackoverflow.com/questions/100003/what-is-a-metaclass-in-python Classes ...
- python——type()、metaclass元类和精简ORM框架
1.type()函数 if __name__ == '__main__': h = hello() h.hello() print(type(hello)) print(type(h)) Hello, ...
随机推荐
- Google addword 策略
https://support.google.com/adwords/answer/1704392?hl=zh-Hans&authuser=0 顾客会用自己的思路去解决生意上的问题,想要拥有自 ...
- SQL SERVER 事务日志 解析
1 基本介绍 每个数据库都具有事务日志,用于记录所有事物以及每个事物对数据库所作的操作. 日志的记录形式需要根据数据库的恢复模式来确定,数据库恢复模式有三种: 完整模式,完全记录事物日志,需要定期进行 ...
- C++拷贝构造&操作符重载
头文件 DString.h如下 #ifndef __DSTRING_H #define __DSTRING_H #endif #include <stddef.h> class DStri ...
- 项目架构开发:数据访问层之UnitOfWork
接上文 项目架构开发:数据访问层之IQuery 本章我们继续IUnitOfWork的开发,从之前的IRepository接口中就可以看出,我们并没有处理单元事务, 数据CUD每次都是立即执行的,这样有 ...
- homebrew常用命令
安装 ruby -e "$(curl -fsSL https://raw.github.com/Homebrew/homebrew/Go/install)" 搜索 brew sea ...
- 1692: [Usaco2007 Dec]队列变换(BZOJ1640强化版)
1692: [Usaco2007 Dec]队列变换 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 682 Solved: 280[Submit][Sta ...
- java爬虫查找四川大学所有学院的网站的网址中的通知和新闻——以计算机学院为例
需求:查找四川大学所有学院的网站的网址中的通知和新闻——以计算机学院为例 流程图 3. 具体步骤 (1) 学院的主页为:http://cs.scu.edu.cn/ 获取该页面的所有内容(本文只获取新闻 ...
- Dell M102ZD-128 —— 拿XP拯救你
查过新浪博客上的记录: http://blog.sina.com.cn/s/articlelist_1259160330_7_1.html 2011年6月买了这台 Dell Inspiron M102 ...
- c# 将匿名类或者集合转Json格式数据一些方法
要说写这个功能呢也是因为工作需要,白天呢上班写个Web页面需要ajax请求后台并将数据以Json格式传会前端,由于公司特殊性吧,不能连外网(很苦比).所以只有等到晚上回家上网边查边写! public ...
- Fundebug上线Node.js错误监控啦
作为全栈JavaScript错误实时监测平台,Fundebug的Node.js实时错误监测服务上线啦,我们能够帮助开发者及时,高效地发现并且解决Node.js错误,从而提高开发效率,并提升用户体验. ...