举例讲解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中使用Inotify监控文件实例
Feb 14 Python
详解supervisor使用教程
Nov 21 Python
Python3 操作符重载方法示例
Nov 23 Python
Python xlwt设置excel单元格字体及格式
Apr 18 Python
pycharm重命名文件的方法步骤
Jul 29 Python
Python计算公交发车时间的完整代码
Feb 12 Python
keras 多gpu并行运行案例
Jun 10 Python
keras Lambda自定义层实现数据的切片方式,Lambda传参数
Jun 11 Python
Python matplotlib图例放在外侧保存时显示不完整问题解决
Jul 28 Python
Django DRF认证组件流程实现原理详解
Aug 17 Python
基于python实现简单C/S模式代码实例
Sep 14 Python
python运算符之与用户交互
Apr 13 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 身份验证方面的函数
2009/10/11 PHP
php下批量挂马和批量清马代码
2011/02/27 PHP
PHP 并发场景的几种解决方案
2019/06/14 PHP
2007/12/23更新创意无限,简单实用(javascript log)
2007/12/24 Javascript
jQuery 浮动广告实现代码
2008/12/25 Javascript
javascript new 需不需要继续使用
2009/07/02 Javascript
jQueryUI如何自定义组件实现代码
2010/11/14 Javascript
js切换div css注意的细节
2012/12/10 Javascript
javascript四舍五入函数代码分享(保留后几位)
2013/12/10 Javascript
jquery实现通用版鼠标经过淡入淡出效果
2014/06/15 Javascript
TypeScript 学习笔记之基本类型
2015/06/19 Javascript
JS正则表达式之非捕获分组用法实例分析
2016/12/28 Javascript
jQuery.Ajax()的data参数类型详解
2017/07/23 jQuery
JS操作时间 - UNIX时间戳的简单介绍(必看篇)
2017/08/16 Javascript
vue的事件绑定与方法详解
2017/08/16 Javascript
解决angular双向绑定无效果,ng-model不能正常显示的问题
2018/10/02 Javascript
微信小程序学习笔记之登录API与获取用户信息操作图文详解
2019/03/29 Javascript
React 全自动数据表格组件——BodeGrid的实现思路
2019/06/12 Javascript
JSX在render函数中的应用详解
2019/09/04 Javascript
vue设置全局访问接口API地址操作
2020/08/14 Javascript
JavaScript实现筛选数组
2021/03/02 Javascript
python访问纯真IP数据库的代码
2011/05/19 Python
跟老齐学Python之有容乃大的list(2)
2014/09/15 Python
Python3 适合初学者学习的银行账户登录系统实例
2017/08/08 Python
python的构建工具setup.py的方法使用示例
2017/10/23 Python
在NumPy中创建空数组/矩阵的方法
2018/06/15 Python
python使用tornado实现简单爬虫
2018/07/28 Python
Python Opencv中用compareHist函数进行直方图比较对比图片
2020/04/07 Python
Windows环境下Python3.6.8 importError: DLLload failed:找不到指定的模块
2020/11/01 Python
html5 button autofocus 属性介绍及应用
2013/01/04 HTML / CSS
美国领先的户外服装与装备用品店:Moosejaw
2016/08/25 全球购物
俄罗斯在线手表和珠宝商店:AllTime
2019/09/28 全球购物
个人能力自我鉴赏
2014/01/25 职场文书
美食节策划方案
2014/05/26 职场文书
小学主题班会教案
2015/08/17 职场文书
mysql中int(3)和int(10)的数值范围是否相同
2021/10/16 MySQL