举例讲解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模块学习 filecmp 文件比较
Aug 27 Python
python函数参数*args**kwargs用法实例
Dec 04 Python
使用Python读写文本文件及编写简单的文本编辑器
Mar 11 Python
一张图带我们入门Python基础教程
Feb 05 Python
Python实现中文数字转换为阿拉伯数字的方法示例
May 26 Python
对Tensorflow中的变量初始化函数详解
Jul 27 Python
浅谈python下含中文字符串正则表达式的编码问题
Dec 07 Python
python使用Geany编辑器配置方法
Feb 21 Python
Python模块相关知识点小结
Mar 09 Python
使用keras实现BiLSTM+CNN+CRF文字标记NER
Jun 29 Python
使用TensorBoard进行超参数优化的实现
Jul 06 Python
Python如何将将模块分割成多个文件
Aug 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
php empty函数 使用说明
2009/08/10 PHP
PHP 数组基础知识小结
2010/08/20 PHP
详解PHP执行定时任务的实现思路
2015/12/21 PHP
在Win2003(64位)中配置IIS6+PHP5.2.17+MySQL5.5的运行环境
2016/04/04 PHP
让回调函数 showResponse 也带上参数的代码
2007/08/13 Javascript
javascript 兼容FF的onmouseenter和onmouseleave的代码
2008/07/19 Javascript
javascript 数组排序函数
2009/08/20 Javascript
基于jquery的滚动新闻列表
2010/06/19 Javascript
js+数组实现网页上显示时间/星期几的实用方法
2013/01/18 Javascript
JS简单实现移动端日历功能示例
2016/12/28 Javascript
javascript 删除数组元素和清空数组的简单方法
2017/02/24 Javascript
想用好React的你必须要知道的一些事情
2017/07/24 Javascript
js实现把时间戳转换为yyyy-MM-dd hh:mm 格式(es6语法)
2017/12/28 Javascript
Javascript网页抢红包外挂实现分享
2018/01/11 Javascript
Bootstrap模态对话框中显示动态内容的方法
2018/08/10 Javascript
Node.js 使用axios读写influxDB的方法示例
2018/10/26 Javascript
cordova+vue+webapp使用html5获取地理位置的方法
2019/07/06 Javascript
VSCode Vue开发推荐插件和VSCode快捷键(小结)
2020/08/08 Javascript
Python制作爬虫采集小说
2015/10/25 Python
python中正则的使用指南
2016/12/04 Python
Python中str is not callable问题详解及解决办法
2017/02/10 Python
python实现csv格式文件转为asc格式文件的方法
2018/03/23 Python
详解python列表生成式和列表生成式器区别
2019/03/27 Python
Python实现查找字符串数组最长公共前缀示例
2019/03/27 Python
Python中dict和set的用法讲解
2019/03/28 Python
Python实现Mysql数据统计及numpy统计函数
2019/07/15 Python
Python检查 云备份进程是否正常运行代码实例
2019/08/22 Python
Python 音频生成器的实现示例
2019/12/24 Python
美国婚礼装饰和活动用品批发供应商:Event Decor Direct
2018/10/12 全球购物
波兰运动鞋网上商店:Distance.pl
2020/07/30 全球购物
公司活动邀请函
2014/01/24 职场文书
2014年健康教育工作总结
2014/11/20 职场文书
硕士学位申请报告
2015/05/15 职场文书
如何在向量化NumPy数组上进行移动窗口
2021/05/18 Python
Python闭包的定义和使用方法
2022/04/11 Python
如何Tomcat中使用ipv6地址
2022/05/06 Servers