举例讲解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 相关文章推荐
zbar解码二维码和条形码示例
Feb 07 Python
python实现的udp协议Server和Client代码实例
Jun 04 Python
Python打印scrapy蜘蛛抓取树结构的方法
Apr 08 Python
python实现批量下载新浪博客的方法
Jun 15 Python
一步步教你用Python实现2048小游戏
Jan 19 Python
神经网络(BP)算法Python实现及应用
Apr 16 Python
详解python算法之冒泡排序
Mar 05 Python
修改 CentOS 6.x 上默认Python的方法
Sep 06 Python
tensorflow 实现自定义梯度反向传播代码
Feb 10 Python
使用python处理题库表格并转化为word形式的实现
Apr 14 Python
Pytorch转onnx、torchscript方式
May 25 Python
Python 用__new__方法实现单例的操作
Dec 11 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 file_exists无效的解决办法
2013/06/26 PHP
getJSON跨域SyntaxError问题分析
2014/08/07 PHP
php实现在服务器端调整图片大小的方法
2015/06/16 PHP
5款适合PHP使用的HTML编辑器推荐
2015/07/03 PHP
yii2.0框架使用 beforeAction 防非法登陆的方法分析
2019/09/11 PHP
24款非常有用的 jQuery 插件分享
2011/04/06 Javascript
最新的10款jQuery内容滑块插件分享
2011/09/18 Javascript
判断访客终端类型集锦
2015/06/05 Javascript
超赞的jQuery图片滑块动画特效代码汇总
2016/01/25 Javascript
animate 实现滑动切换效果【实例代码】
2016/05/05 Javascript
微信小程序中单位rpx和rem的使用
2016/12/06 Javascript
nodejs个人博客开发第一步 准备工作
2017/04/12 NodeJs
Javascript(es2016) import和require用法和区别详解
2017/08/11 Javascript
AngularJS 打开新的标签页实现代码
2017/09/07 Javascript
一文让你彻底搞清楚javascript中的require、import与export
2017/09/24 Javascript
详解vue-cli 接口代理配置
2017/12/13 Javascript
详解三种方式解决vue中v-html元素中标签样式
2018/11/22 Javascript
ES6 Map结构的应用实例分析
2019/06/26 Javascript
ES6中异步对象Promise用法详解
2019/07/31 Javascript
一文看懂如何简单实现节流函数和防抖函数
2019/09/05 Javascript
微信小程序云函数添加数据到数据库的方法
2020/03/04 Javascript
[01:09:40]Newbee vs Pain 2018国际邀请赛小组赛BO2 第一场 8.16
2018/08/17 DOTA
python下函数参数的传递(参数带星号的说明)
2010/09/19 Python
python通过定义一个类实例作为ftp回调方法
2015/05/04 Python
Python通用循环的构造方法实例分析
2018/12/19 Python
计算机二级python学习教程(2) python语言基本语法元素
2019/05/16 Python
关于Python Tkinter Button控件command传参问题的解决方式
2020/03/04 Python
Spy++的使用方法及下载教程
2021/01/29 Python
CSS3悬停效果案例应用
2012/11/21 HTML / CSS
澳大利亚家具和家居用品购物网站:Zanui
2018/12/29 全球购物
西雅图的买手店:Totokaelo
2019/10/19 全球购物
中学生团员自我评价分享
2013/12/07 职场文书
人事专员的岗位职责
2014/03/01 职场文书
机关干部作风建设剖析材料
2014/10/23 职场文书
初中团委工作总结
2015/08/13 职场文书
干货:如何写好观后感 !
2019/05/21 职场文书