python中的元类_python中的元类
类也是对象,但是类有创建对象的能力
动态创建一个类:
classmonkey():defbanana(self):print 'banana!'
defapple(self):print 'i want apple!'monkey_child= type('monkey_child', (monkey,), {'apple': apple})
hasattr(monkey,'apple')
false
hasattr(monkey_child,'apple')
true
type的语法:type(类名,父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))
创建类的就是元类,type是所有类的元类,类属性__class__可以看到元类是什么
>>> a=1
>>>type(a)
>>> type(a.__class__)
创建一个类的过程:搜索__metaclass__是否有指定,否则搜索父类中的__metaclass__,最终应该找到type或是type的子类
由于python中鸭子类型的概念,__metaclass__实际上不一定是一个类,也可以是一个函数
defupper_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 inattrs)returntype(future_class_name, future_class_parents, uppercase_attr)classFoo(object):__metaclass__ =upper_attr
bar= 'aip'
printFoo.BAR>>>'aip'
在Python3中我们在定义类时通过传入metaclass的参数来设定,如上代码就应该写成class Foo(metaclass=upper_attr)。
metaclass可以是一个类
classUpperAttrMetaclass(type):def __new__(cls, name, bases, dct):
attrs= ((name, value) for name, value in dct.items() if not name.startswith('__')
uppercase_attr= dict((name.upper(), value) for name, value inattrs)return type.__new__(cls, name, bases, uppercase_attr)
__new__在__init__之前被调用,用于创建和返回对象,由__new__是一个类方法,我们需要传入实例对象cls。
为了表明继承关系,以上代码可以写成
classUpperAttrMetaclass(type):def __new__(cls, name, bases, dct):
attrs= ((name, value) for name, value in dct.items() if not name.startswith('__'))
uppercase_attr= dict((name.upper(), value) for name, value inattrs)return super(UpperAttrMetaclass, cls).__new__(cls, name, bases, uppercase_attr)
为什么要用metaclass类而不是函数?
由于__metaclass__可以接受任何可调用的对象,那为何还要使用类呢,因为很显然使用类会更加复杂啊?这里有好几个原因:
1) 意图会更加清晰。当你读到UpperAttrMetaclass(type)时,你知道接下来要发生什么。
2) 你可以使用OOP编程。元类可以从元类中继承而来,改写父类的方法。元类甚至还可以使用元类。
3) 你可以把代码组织的更好。当你使用元类的时候肯定不会是像我上面举的这种简单场景,通常都是针对比较复杂的问题。将多个方法归总到一个类中会很有帮助,也会使得代码更容易阅读。
4) 你可以使用__new__, __init__以及__call__这样的特殊方法。它们能帮你处理不同的任务。就算通常你可以把所有的东西都在__new__里处理掉,有些人还是觉得用__init__更舒服些。
根据http://python3-cookbook.readthedocs.io/zh_CN/latest/c08/p07_calling_method_on_parent_class.html 可以知道,我们应该在继承并改写的代码中尽量使用super访问父类,而不是直接访问父类。
classUpperAttrMetaclass(type):def __new__(cls, name, bases, dct):
attrs= ((name, value) for name, value in dct.items() if not name.startswith('__'))
uppercase_attr= dict((name.upper(), value) for name, value inattrs)return super(UpperAttrMetaclass, cls).__new__(cls, name, bases, uppercase_attr)
参考:http://blog.jobbole.com/21351/
其中有一个Django的ORM的例子,学习之
python中的元类_python中的元类相关推荐
- python元类_python中的元类 metaclass
python中的元类 metaclass 在python中,类(class)本身也是一个实例对象, 它的类型则是元类, 如果没有指明, 则自定义类的类型是type. 换言之, 我们所定义的普通类都是t ...
- python中的元类_Python中的元类(metaclass)
提问者自称已经掌握了有关Python OOP编程中的各种概念,但始终觉得元类(metaclass)难以理解.他知道这肯定和自身有关,但仍然觉得不太明白,希望大家可以给出一些实际的例子和代码片段以帮助理 ...
- python object类_Python中一切皆对象,这个对象究竟是什么?
点击上方蓝字CGRnDStudio关注我们" CG TD编程技术相关领域自媒体 " 作者:古明地盆 https://www.cnblogs.com/traditional/p/13 ...
- python如何定义类_python中定义类
广告关闭 腾讯云11.11云上盛惠 ,精选热门产品助力上云,云服务器首年88元起,买的越多返的越多,最高返5000元! 类的定义python中,定义类是通过class关键字,例如我们定义一个存储学生信 ...
- python 类中定义类_Python中的动态类定义
python 类中定义类 Here's a neat Python trick you might just find useful one day. Let's look at how you ca ...
- python class类_python中的class(类)
编码注释: 在源文件的第一行或第二行写入如下内容: # -*- coding:gbk -*- # 设置源文件编码格式为:gbk 或 # -*- coding:utf-8 -*- # 设置源文件编码格式 ...
- python什么时候用类_python中什么时候使用自定义类
Python中所有的数据都是对象,它提供了许多高级的内建数据类型,功能强大,使用方便,是Python的优点之一.那么什么时候使用自定义类呢? 比如设计一个Person类,如果不使用自定义类,可以这样做 ...
- python类_Python中的类
Python和Java都是面向对象的语言,对象从类中获取,类指的是同一类具有相同特征的事物,比如拉布拉多,柯基,哈士奇,它们都是狗,具有狗的相同特征,所以可以被归为一类Dog,Python中类的使用与 ...
- python编写ATM类_Python中编写类的各种技巧和方法
有关 Python 内编写类的各种技巧和方法(构建和初始化.重载操作符.类描述.属性访问控制.自定义序列.反射机制.可调用对象.上下文管理.构建描述符对象.Pickling).你可以把它当作一个教程, ...
最新文章
- 编程思想之多线程与多进程——以操作系统的角度述说线程与进程
- 以使用QSqlQuery向数据库中插入数据为例,做一个小结
- 工程化专题之Maven(上)
- linux测试网络是否连通ping、telnet命令
- transformers model inputs
- drawforeground只有鼠标事件进入才刷新_罗技各系鼠标测评(2020年12月更新)
- Docker 指定数据储存目录
- 10.related product , up-sell product and cross-sells
- hbase占用内存过高_为什么不建议在 HBase 中使用过多的列族
- rc.local文件开机不执行
- OutLook添加网易邮箱,QQ邮箱
- SSM+高校教室管理系统 毕业设计-附源码181523
- 【国内chatgpt使用方法合集】(5月22日已更新)
- 移动端H5页面遇到的问题总结
- translate,transform和transition的区别与联系
- Booth编码以及运算实例
- 关于火线、零线、地线
- 这家5G边缘计算企业科创板首发过会!
- 为PDF自动插入目录
- 中国联通5G白皮书大全(2018年发布)-随时下载