python的元类
来源:互联网 发布:Linux 线程 sched_fifo 编辑:程序博客网 时间:2024/04/30 01:08
Python中的一切都是对象,无论是int,字符串,函数还是类。对象分为两类,实例对象和类对象。类对象就是类。我们可以这么理解,类实例化是实例对象,元类实例化就是类。
type是python内置的唯一元类。当然你可以自己开发元类。int str等则是python内置的类。一切类都是元类的实例化,包括元类自己。
a=2print(a.__class__)//python3输出<class 'int'>print(a.__class__.__class__)//python3输出<class 'type'>print(type.__class__)//python3输出<class 'type'>
既然type是元类,那么我们实例化type就可以得到一个类。实际上也确实如此
def fn(self, name='world'): # 先定义函数 print('Hello, %s.' % name)Hello = type('Hello', (object,), dict(hello=fn))//Hello已经是一个类了h = Hello()print(h.__class__)//输出<class '__main__.Hello'>
故事如果到这里结束,就是证明了一个问题,python一切都是对象,简洁明了。
问题的下一个关键点,在于类的metaclass属性。并不是所有类都有metaclass,除非你显示的指定它。如果你在类中指定他,他将在该类中有效。如果你在模块中指定它,则对于整个模块的所有类都有效。
metaclass可以在模块和类中定义。可以是一个方法,也可以是一个类。如果他是一个方法,则他应该返回一个类对象,如下例子所示:
# 元类会自动将你通常传给‘type’的参数作为自己的参数传入def upper_attr(future_class_name, future_class_parents, future_class_attr): '''返回一个类对象,将属性都转为大写形式''' # 选择所有不以'__'开头的属性 attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__')) # 将它们转为大写形式 uppercase_attr = dict((name.upper(), value) for name, value in attrs) # 通过'type'来做类对象的创建 return type(future_class_name, future_class_parents, uppercase_attr)__metaclass__ = upper_attr # 这会作用到这个模块中的所有类class Foo(object): # 我们也可以只在这里定义__metaclass__,这样就只会作用于这个类中 bar = 'bip'
如果metaclass和他的名字元类一样是一个类,如下例子所示,此时,要求其__new__方法必须返回一个类对象。
# 请记住,'type'实际上是一个类,就像'str'和'int'一样# 所以,你可以从type继承class UpperAttrMetaClass(type): # __new__ 是在__init__之前被调用的特殊方法 # __new__是用来创建对象并返回之的方法 # 而__init__只是用来将传入的参数初始化给对象 # 你很少用到__new__,除非你希望能够控制对象的创建 # 这里,创建的对象是类,我们希望能够自定义它,所以我们这里改写__new__ # 如果你希望的话,你也可以在__init__中做些事情 # 还有一些高级的用法会涉及到改写__call__特殊方法,但是我们这里不用 def __new__(upperattr_metaclass, future_class_name, future_class_parents, future_class_attr): attrs = ((name, value) for name, value in future_class_attr.items() if not name.startswith('__')) uppercase_attr = dict((name.upper(), value) for name, value in attrs) return type(future_class_name, future_class_parents, uppercase_attr)
因为上面的元类是直接从type继承的,所以上面代码最后一句可以改为
return type.__new__(upperattr_metaclass, future_class_name, future_class_parents, uppercase_attr)
或者
return super(UpperAttrMetaclass, cls).__new__(cls, name, bases, uppercase_attr)
元类是动态改变类的属性名和属性值的办法。diango中的model.py就采用这种办法,从而将用户的model.py转化为一个真实的数据库对象。
阅读全文
0 0
- python的元类
- Python元类的理解
- python 元类的理解
- python的元类---类的类
- 对python元类概念的理解
- python的元类思维导图
- 深刻理解Python的元类
- Python元类
- Python元类
- Python之元类
- python学习~元类
- python 元类
- python中的元类
- 关于python元类
- python元类分析
- python元类__metaclass__
- python中的元类
- Python中的元类
- 链表的创建
- D.Game with Pearls
- 试验性的Numpy教程
- Android数据库
- (二)——添加网络权限和WebView访问网页
- python的元类
- 大数据学习之——Zookeeper安装
- NXP第十三届智能车竞赛就此拉开帷幕(更新中)
- Android面试题整理(1)
- early_irq_init
- 大数据学习之——kafka安装部署
- git
- do{...}while(0)的意义和用法
- c#事件总结