举例讲解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正则表达式 re模块使用说明
May 19 Python
在arcgis使用python脚本进行字段计算时是如何解决中文问题的
Oct 18 Python
深入理解NumPy简明教程---数组2
Dec 17 Python
python对于requests的封装方法详解
Jan 03 Python
python tools实现视频的每一帧提取并保存
Mar 20 Python
python打印异常信息的两种实现方式
Dec 24 Python
解决torch.autograd.backward中的参数问题
Jan 07 Python
tensorflow之tf.record实现存浮点数数组
Feb 17 Python
Python基于pandas爬取网页表格数据
May 11 Python
Python内置函数property()如何使用
Sep 01 Python
python基于OpenCV模板匹配识别图片中的数字
Mar 31 Python
Python合并pdf文件的工具
Jul 01 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安装memcached扩展笔记
2015/05/28 PHP
PHP register_shutdown_function()函数的使用示例
2015/06/23 PHP
PHP版QQ互联OAuth示例代码分享
2015/07/05 PHP
apache集成php7.3.5的详细步骤
2019/06/20 PHP
兼容FireFox 的 js 日历 支持时间的获取
2009/03/04 Javascript
javascript 精粹笔记
2010/05/09 Javascript
自己动手制作jquery插件之自动添加删除行的实现
2011/10/13 Javascript
jQuery AJAX实现调用页面后台方法和web服务定义的方法分享
2012/03/01 Javascript
ie支持function.bind()方法实现代码
2012/12/27 Javascript
JavaScript遍历table表格中的某行某列并打印其值
2014/07/08 Javascript
jQuery简单实现QQ空间点赞已经取消点赞
2015/04/02 Javascript
jQuery处理图片加载失败的常用方法
2015/06/08 Javascript
js游戏人物上下左右跑步效果代码分享
2015/08/28 Javascript
jQuery对象的链式操作用法分析
2016/05/10 Javascript
jquery遍历标签中自定义的属性方法
2016/09/17 Javascript
JavaScript数据结构之二叉树的查找算法示例
2017/04/13 Javascript
javascript回调函数的概念理解与用法分析
2017/05/27 Javascript
微信小程序组件 marquee实例详解
2017/06/23 Javascript
Node.JS段点续传:Nginx配置文件分段下载功能的实现方法
2018/03/12 Javascript
ES6 Promise对象的应用实例分析
2019/06/27 Javascript
js贪心算法 钱币找零问题代码实例
2019/09/11 Javascript
通过实例了解Nodejs模块系统及require机制
2020/07/16 NodeJs
[44:50]DOTA2上海特级锦标赛B组小组赛#2 VG VS Fnatic第二局
2016/02/26 DOTA
Python help()函数用法详解
2014/03/11 Python
python字符串中的单双引
2017/02/16 Python
使用Python实现一个栈判断括号是否平衡
2018/08/23 Python
PyTorch加载自己的数据集实例详解
2020/03/18 Python
js实现弹框效果
2021/03/24 Javascript
教师旷工检讨书
2014/01/18 职场文书
2014年小学体育工作总结
2014/12/11 职场文书
幼儿园奖惩制度范本
2015/08/05 职场文书
大学组织委员竞选稿
2015/11/21 职场文书
《我的长生果》教学反思
2016/02/20 职场文书
go语言基础 seek光标位置os包的使用
2021/05/09 Golang
mysql数据插入覆盖和时间戳的问题及解决
2022/03/25 MySQL
ubuntu下常用apt命令介绍
2022/06/05 Servers