举例讲解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 和 lint 删除项目无用资源的方法
Dec 20 Python
使用python将图片按标签分入不同文件夹的方法
Dec 08 Python
Python数据分析:手把手教你用Pandas生成可视化图表的教程
Dec 15 Python
在Python中将函数作为另一个函数的参数传入并调用的方法
Jan 22 Python
Python正则表达式和re库知识点总结
Feb 11 Python
网易2016研发工程师编程题 奖学金(python)
Jun 19 Python
Python实现Canny及Hough算法代码实例解析
Aug 06 Python
Python计算矩阵的和积的实例详解
Sep 10 Python
如何用 Python 制作 GitHub 消息助手
Feb 20 Python
详解用Python把PDF转为Word方法总结
Apr 27 Python
浅谈Python从全局与局部变量到装饰器的相关知识
Jun 21 Python
Python实现查询剪贴板自动匹配信息的思路详解
Jul 09 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
php数组函数序列 之shuffle()和array_rand() 随机函数使用介绍
2011/10/29 PHP
PHP实现多进程并行操作的详解(可做守护进程)
2013/06/18 PHP
php获取文件夹路径内的图片以及分页显示示例
2014/03/11 PHP
PHP Opcache安装和配置方法介绍
2015/05/28 PHP
php实现基于openssl的加密解密方法
2016/09/30 PHP
用prototype实现的简单小巧的多级联动菜单
2007/03/24 Javascript
身份证号码前六位所代表的省,市,区, 以及地区编码下载
2007/04/12 Javascript
javascript 二进制运算技巧解析
2012/11/27 Javascript
Javascript无参数和有参数类继承问题解决方法
2015/03/02 Javascript
利用vue写todolist单页应用
2016/12/15 Javascript
NodeJs安装npm包一直失败的解决方法
2017/04/28 NodeJs
详解基于vue-cli3快速发布一个fullpage组件
2019/03/08 Javascript
js实现计时器秒表功能
2019/12/16 Javascript
Python迭代器和生成器介绍
2015/03/06 Python
python基于pyDes库实现des加密的方法
2017/04/29 Python
分享一个简单的python读写文件脚本
2017/11/25 Python
Python绘制3d螺旋曲线图实例代码
2017/12/20 Python
Python使用 Beanstalkd 做异步任务处理的方法
2018/04/24 Python
Python numpy实现二维数组和一维数组拼接的方法
2018/06/05 Python
python xlsxwriter创建excel图表的方法
2018/06/11 Python
Python异常原理及异常捕捉实现过程解析
2020/03/25 Python
Python如何使用队列方式实现多线程爬虫
2020/05/12 Python
Django admin管理工具TabularInline类用法详解
2020/05/14 Python
HTML5表单验证特性(知识点小结)
2020/03/10 HTML / CSS
进程的查看和调度分别使用什么命令
2013/12/14 面试题
过程装备与控制工程专业个人的求职信
2013/12/01 职场文书
网络程序员自荐信
2014/01/25 职场文书
高中体育教学反思
2014/01/29 职场文书
感恩节红领巾广播稿
2014/02/11 职场文书
新闻编辑专业自荐信
2014/07/02 职场文书
法定代表人授权委托书格式
2014/10/14 职场文书
公路局群众路线教育实践活动第一阶段工作汇报
2014/10/25 职场文书
公务员政审个人总结
2015/02/12 职场文书
求职自我推荐信
2015/03/24 职场文书
浅谈MySQL 亿级数据分页的优化
2021/06/15 MySQL
详解Go语言Slice作为函数参数的使用
2021/07/02 Golang