举例讲解Python中metaclass元类的创建与使用


Posted in Python onJune 30, 2016

元类是可以让你定义某些类是如何被创建的。从根本上说,赋予你如何创建类的控制权。
元类也是一个类,是一个type类。
 
元类一般用于创建类。在执行类定义时,解释器必须要知道这个类的正确的元类,如果此属性没有定义,它会向上查找父类中的__metaclass__属性。如果还没发现,就查找全局变量。
 
对于传统类来说,它们的元类是types.ClassType。
 
元类也有构造器,传递三个参数:类名,从基类继承数据的元组,和类属性字典。
下面我们来定义一个元类,要求写类的时候必须给类提供一个__str__()方法,如果没有提供__repr__()方法,
则给你警告。

from warnings import warn
#元类需要继承type类
class ReqStrSugRepr(type):
  def __init__(cls, name, bases, attrd):
  #构造函数需要传递的参数为类名,基类,类属性字典
    super(ReqStrSugRepr, cls).__init__(name, bases, attrd)
    # 判断__str__字符串是否在类的属性字典里
    if '__str__' not in attrd:
      raise TypeError('Class requires overriding of __str__()')

    if '__repr__' not in attrd:
      warn('Class suggests overriding of __repr__()\n', stacklevel=3)

class Foo(object):
  #给类指定元类 
  __metaclass__ = ReqStrSugRepr

  def foo(self):
    pass
#这一段代码不用创建类来测试,直接运行一下就会报错,可见元类的功力。

举例讲解Python中metaclass元类的创建与使用

type

type函数可以查看一个变量的类型, 比如:

# <type 'int'>
# <type 'str'>
type(1)     
type('mink')

type函数还可以创建一个新的对象
type接受三个参数,name, bases, dict 第一个接受类名,第二个参数接受父类(元组形式),第三个参数接受属性和方法(字典形式)

X = type('X', (object,), dict(a=1))
# 等于
class X(object):
  a = 1

下面是接受函数的方法

def say(self):
  print 'hello'

X = type('X', (object,), dict(say=say))
x = X()

# pirnt hello
x.say()

元类

我们都知道通过类可以创建处实例对象,而元类就是创建出类对象的类。type可以创建出类对象也就是说type就是一个元类。

metaclass 属性

如果想使用元类创建类对象就需要对该对象添加一个__metaclass__属性。当然你首先得有一个元类

class PrivateMetaclass(type):
  def __new__(cls, name, parents, attrs):
    attrs = dict(('__%s' % k, v) for k, v in attrs.itmes())
    return super(PrivateMetaclass, cls).__new__(cls, name, parents, attrs)

class A(object):
  __metaclass__ = PrivateMetaclass
  a = 1
  b = 2

a = A()
# raise AttributeError
print a.a, a.b 

# print 1, 2
print a.__a, a.__b

这样你就可以通过元类来修改类的一些特性,上面的就是修改变量为私有变量.

Python 相关文章推荐
Python实现网络端口转发和重定向的方法
Sep 19 Python
Python爬虫之xlml解析库(全面了解)
Aug 08 Python
Python使用pip安装pySerial串口通讯模块
Apr 20 Python
Python实现字符串匹配的KMP算法
Apr 04 Python
python 实现在tkinter中动态显示label图片的方法
Jun 13 Python
python顺序执行多个py文件的方法
Jun 29 Python
win8.1安装Python 2.7版环境图文详解
Jul 01 Python
python把ipynb文件转换成pdf文件过程详解
Jul 09 Python
Python 迭代,for...in遍历,迭代原理与应用示例
Oct 12 Python
在Python中字符串、列表、元组、字典之间的相互转换
Nov 15 Python
基于python3的socket聊天编程
Feb 17 Python
python基于exchange函数发送邮件过程详解
Nov 06 Python
在Python中定义和使用抽象类的方法
Jun 30 #Python
Python中functools模块的常用函数解析
Jun 30 #Python
深入浅析Python中join 和 split详解(推荐)
Jun 30 #Python
Python列出一个文件夹及其子目录的所有文件
Jun 30 #Python
django之常用命令详解
Jun 30 #Python
全面了解Python环境配置及项目建立
Jun 30 #Python
浅谈Python 集合(set)类型的操作——并交差
Jun 30 #Python
You might like
《魔兽世界》惊魂幻象将获得调整
2020/03/08 其他游戏
php 5.6版本中编写一个PHP扩展的简单示例
2015/01/20 PHP
php视频拍照上传头像功能实现代码分享
2015/10/08 PHP
php获取excel文件数据
2017/04/21 PHP
Jquery 表单取值赋值的一些基本操作
2009/10/11 Javascript
基于jquery的获取mouse坐标插件的实现代码
2010/04/01 Javascript
jQuery选中select控件 无法设置selected的解决方法
2010/09/01 Javascript
UpdatePanel和Jquery冲突的解决方法
2013/04/01 Javascript
JavaScript的继承的封装介绍
2013/10/15 Javascript
javascript为下拉列表动态添加数据项
2014/05/23 Javascript
JavaScript动态改变HTML页面元素例如添加或删除
2014/08/10 Javascript
node.js开机自启动脚本文件
2014/12/24 Javascript
js实现密码强度检验
2017/01/15 Javascript
微信小程序实现带刻度尺滑块功能
2017/03/29 Javascript
JS 组件系列之Bootstrap Table 冻结列功能IE浏览器兼容性问题解决方案
2017/06/30 Javascript
[03:49]辉夜杯现场龙骑士COSER秀情商“我喜欢芬队!”
2015/12/27 DOTA
Python对象的深拷贝和浅拷贝详解
2014/08/25 Python
python插入数据到列表的方法
2015/04/30 Python
Python实现Smtplib发送带有各种附件的邮件实例
2017/06/05 Python
详解Python requests 超时和重试的方法
2018/12/18 Python
在numpy矩阵中令小于0的元素改为0的实例
2019/01/26 Python
django drf框架自带的路由及最简化的视图
2019/09/10 Python
Python 异步协程函数原理及实例详解
2019/11/13 Python
pytorch中tensor张量数据类型的转化方式
2019/12/31 Python
关于HTML5你必须知道的28个新特性,新技巧以及新技术
2012/05/28 HTML / CSS
HTML5移动端手机网站开发流程
2016/04/25 HTML / CSS
如何用Python来进行查询和替换一个文本字符串
2014/01/02 面试题
2014年教师节活动总结
2014/08/29 职场文书
司机个人年终总结
2015/03/03 职场文书
幼儿园家长工作总结2015
2015/04/25 职场文书
2015年医院保卫科工作总结
2015/07/23 职场文书
2015年店长个人工作总结
2015/10/23 职场文书
2019年作为一名实习生的述职报告
2019/09/29 职场文书
有关信念的名言语录集锦
2019/12/06 职场文书
浅谈由position属性引申的css进阶讨论
2021/05/25 HTML / CSS
了解MySQL查询语句执行过程(5大组件)
2022/08/14 MySQL