举例讲解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 相关文章推荐
在Docker上部署Python的Flask框架的教程
Apr 08 Python
python3实现ftp服务功能(服务端 For Linux)
Mar 24 Python
python 实现在Excel末尾增加新行
May 02 Python
对tf.reduce_sum tensorflow维度上的操作详解
Jul 26 Python
django框架面向对象ORM模型继承用法实例分析
Jul 29 Python
Python面向对象封装操作案例详解 II
Jan 02 Python
python剪切视频与合并视频的实现
Mar 03 Python
使用pandas库对csv文件进行筛选保存
May 25 Python
Python替换NumPy数组中大于某个值的所有元素实例
Jun 08 Python
安装并免费使用Pycharm专业版(学生/教师)
Sep 24 Python
python之随机数函数的实现示例
Dec 30 Python
python 制作磁力搜索工具
Mar 04 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/04 星际争霸
PHP $_FILES函数详解
2011/03/09 PHP
二进制交叉权限微型php类分享
2014/02/07 PHP
详解WordPress中用于更新和获取用户选项数据的PHP函数
2016/03/08 PHP
PHP 数组遍历foreach语法结构及实例
2016/06/13 PHP
百度留言本js 大家可以参考下
2009/10/13 Javascript
javascrip客户端验证文件大小及文件类型并重置上传
2011/01/12 Javascript
js 鼠标移动显示图片的简单实例
2013/12/25 Javascript
JS和Jquery获取和修改label的值的示例代码
2014/01/15 Javascript
JS实现带圆弧背景渐变效果的导航菜单代码
2015/10/13 Javascript
JavaScript实现图片滑动切换的代码示例分享
2016/03/06 Javascript
JS条形码(一维码)插件JsBarcode用法详解【编码类型、参数、属性】
2017/04/19 Javascript
jquery实现左右轮播切换效果
2018/01/01 jQuery
nodejs+express搭建多人聊天室步骤
2018/02/12 NodeJs
Jquery属性的获取/设置及样式添加/删除操作技巧分析
2019/12/23 jQuery
JavaScript实现联动菜单特效
2020/01/07 Javascript
JavaScript中arguments的使用方法详解
2020/12/20 Javascript
Python中函数及默认参数的定义与调用操作实例分析
2017/07/25 Python
Python Numpy计算各类距离的方法
2019/07/05 Python
ipad上运行python的方法步骤
2019/10/12 Python
python语言是免费还是收费的?
2020/06/15 Python
canvas中普通动效与粒子动效的实现代码示例
2019/01/03 HTML / CSS
英国领先的珍珠首饰品牌:Orchira
2016/09/11 全球购物
工商治理实习生的自我评价分享
2014/02/20 职场文书
交通事故赔偿协议书
2014/04/15 职场文书
人力资源管理毕业求职信
2014/08/05 职场文书
机票销售员态度不好检讨书
2014/09/27 职场文书
出国签证在职证明范本
2014/11/24 职场文书
幼儿园老师个人总结
2015/02/28 职场文书
解除劳动合同通知书范本
2015/04/16 职场文书
2015年教务工作总结
2015/05/23 职场文书
校园歌手大赛主持词
2015/07/03 职场文书
少先队中队工作总结
2015/08/14 职场文书
最美劳动诗,致敬所有的劳动者!
2019/07/12 职场文书
教你解决往mysql数据库中存入汉字报错的方法
2021/05/06 MySQL
MySQL 分页查询的优化技巧
2021/05/12 MySQL