举例讲解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异常处理慎用“except:pass”建议
Apr 02 Python
python3判断url链接是否为404的方法
Aug 10 Python
BP神经网络原理及Python实现代码
Dec 18 Python
Python查找数组中数值和下标相等的元素示例【二分查找】
Feb 13 Python
详解python数据结构和算法
Apr 18 Python
python打印异常信息的两种实现方式
Dec 24 Python
Python猴子补丁知识点总结
Jan 05 Python
Python Numpy中数据的常用保存与读取方法
Apr 01 Python
Python生成随机验证码代码实例解析
Jun 09 Python
Django路由层URLconf作用及原理解析
Sep 24 Python
python RSA加密的示例
Dec 09 Python
Python实现京东抢秒杀功能
Jan 25 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 阴历-农历-转换类代码
2012/01/16 PHP
PHP计算指定日期所在周的开始和结束日期的方法
2015/03/24 PHP
PHP浮点数精度问题汇总
2015/05/13 PHP
基于Laravel实现的用户动态模块开发
2017/09/21 PHP
Laravel统计一段时间间隔的数据方法
2019/10/09 PHP
浅析PHP中的 inet_pton 网络函数
2019/12/16 PHP
TP5框架实现签到功能的方法分析
2020/04/05 PHP
jQuery代码优化 事件委托篇
2011/11/01 Javascript
js变量、作用域及内存详解
2014/09/23 Javascript
Javascript简写条件语句(推荐)
2016/06/12 Javascript
vue-router单页面路由
2017/06/17 Javascript
js分页之前端代码实现和请求处理
2017/08/04 Javascript
jQuery基于闭包实现的显示与隐藏div功能示例
2018/06/09 jQuery
微信公众号获取用户地理位置并列出附近的门店的示例代码
2019/07/25 Javascript
微信小程序全选多选效果实现代码解析
2020/01/21 Javascript
ES6 Iterator遍历器原理,应用场景及相关常用知识拓展详解
2020/02/15 Javascript
Python运行的17个时新手常见错误小结
2012/08/07 Python
python使用循环实现批量创建文件夹示例
2014/03/25 Python
python操作redis的方法
2015/07/07 Python
python实现二维码扫码自动登录淘宝
2016/12/27 Python
解决Python 爬虫URL中存在中文或特殊符号无法请求的问题
2018/05/11 Python
使用Python做定时任务及时了解互联网动态
2019/05/15 Python
pygame实现烟雨蒙蒙下彩虹雨
2019/11/11 Python
python实现两个字典合并,两个list合并
2019/12/02 Python
通过实例学习Python Excel操作
2020/01/06 Python
PyCharm中配置PySide2的图文教程
2020/06/18 Python
Django中Aggregation聚合的基本使用方法
2020/07/09 Python
python 5个实用的技巧
2020/09/27 Python
北京某科技有限公司C# .net笔试题
2014/09/27 面试题
业务部门经理岗位职责
2014/02/23 职场文书
小学生学习雷锋倡议书
2014/05/15 职场文书
房地产推广策划方案
2014/05/19 职场文书
爱的承诺书
2015/01/20 职场文书
观看焦裕禄观后感
2015/06/09 职场文书
2019让人心动的商业计划书
2019/06/27 职场文书
MySQL创建表操作命令分享
2022/03/25 MySQL