举例讲解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中self的用法
Jun 04 Python
Python信息抽取之乱码解决办法
Jun 29 Python
深入理解Python 关于supper 的 用法和原理
Feb 28 Python
解决python删除文件的权限错误问题
Apr 24 Python
python邮件发送smtplib使用详解
Jun 16 Python
django解决跨域请求的问题
Nov 11 Python
Python队列、进程间通信、线程案例
Oct 25 Python
pytorch点乘与叉乘示例讲解
Dec 27 Python
pytorch之ImageFolder使用详解
Jan 06 Python
django配置app中的静态文件步骤
Mar 27 Python
keras读取训练好的模型参数并把参数赋值给其它模型详解
Jun 15 Python
python+selenium+chrome实现淘宝购物车秒杀自动结算
Jan 07 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弹出提示框并跳转到新页面即重定向到新页面
2014/01/24 PHP
PHP获取mysql数据表的字段名称和详细信息的方法
2014/09/27 PHP
PHP微信开发之微信消息自动回复下所遇到的坑
2016/05/09 PHP
Yii净化器CHtmlPurifier用法示例(过滤不良代码)
2016/07/15 PHP
PHP微信PC二维码登陆的实现思路
2017/07/13 PHP
ThinkPHP框架获取最后一次执行SQL语句及变量调试简单操作示例
2018/06/13 PHP
PHP面向对象程序设计子类扩展父类(子类重新载入父类)操作详解
2019/06/14 PHP
深入浅析安装PhpStorm并激活的步骤详解
2020/09/17 PHP
jQuery DIV弹出效果实现代码
2009/07/03 Javascript
Jquery Select操作方法集合脚本之家特别版
2010/05/17 Javascript
基于jquery ajax 用户无刷新登录方法详解
2012/04/28 Javascript
JS按字节截取字符长度实例
2013/11/20 Javascript
AngularJS中的表单简单入门
2016/07/28 Javascript
在点击div中的p时,如何阻止事件冒泡
2017/02/07 Javascript
利用js定义一个导航条菜单
2017/03/14 Javascript
Javascript实现基本运算器
2017/07/15 Javascript
addeventlistener监听scroll跟touch(实例讲解)
2017/08/04 Javascript
VUE实现一个分页组件的示例
2017/09/13 Javascript
在vue中多次调用同一个定义全局变量的实例
2018/09/25 Javascript
微信小程序实现省市区三级地址选择
2020/06/21 Javascript
优化Vue项目编译文件大小的方法步骤
2019/05/27 Javascript
小程序自动化测试的示例代码
2020/08/11 Javascript
python 正则式使用心得
2009/05/07 Python
python 去除二维数组/二维列表中的重复行方法
2019/01/23 Python
基于Keras中Conv1D和Conv2D的区别说明
2020/06/19 Python
Django如何实现密码错误报错提醒
2020/09/04 Python
CSS3教程(7):CSS3嵌入字体
2009/04/02 HTML / CSS
韩国家庭购物网上商店:Nsmall
2017/05/07 全球购物
全球第二大家装零售商:Lowe’s
2018/01/13 全球购物
职业技术学校毕业生推荐信
2013/12/03 职场文书
平安工地建设方案
2014/05/06 职场文书
2014年机关后勤工作总结
2014/12/16 职场文书
2015感人爱情寄语
2015/02/26 职场文书
企业工会工作总结2015
2015/05/13 职场文书
观看禁毒宣传片后的感想
2015/08/11 职场文书
Django+Nginx+uWSGI 定时任务的实现方法
2022/01/22 Python