举例讲解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 相关文章推荐
Java中重定向输出流实现用文件记录程序日志
Jun 12 Python
Python语法快速入门指南
Oct 12 Python
python监控键盘输入实例代码
Feb 09 Python
Python爬虫包BeautifulSoup实例(三)
Jun 17 Python
代码详解django中数据库设置
Jan 28 Python
浅谈python的输入输出,注释,基本数据类型
Apr 02 Python
Python实现的爬取百度贴吧图片功能完整示例
May 10 Python
python网络编程之多线程同时接受和发送
Sep 03 Python
序列化Python对象的方法
Aug 01 Python
Django项目创建及管理实现流程详解
Oct 13 Python
python中操作文件的模块的方法总结
Feb 04 Python
Python道路车道线检测的实现
Jun 27 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
phpinfo 系统查看参数函数代码
2009/06/05 PHP
PHP几个实用自定义函数小结
2016/01/25 PHP
php简单解析mysqli查询结果的方法(2种方法)
2016/06/29 PHP
自制PHP框架之模型与数据库
2017/05/07 PHP
PHP实现动态删除XML数据的方法示例
2018/03/30 PHP
javascript Prototype 对象扩展
2009/05/15 Javascript
使用jQuery解决IE与FireFox下createElement方法的差异
2013/11/14 Javascript
JavaScript中的apply和call函数详解
2014/07/20 Javascript
第一次记录Bootstrap table学习笔记(1)
2017/05/18 Javascript
JS实现发送短信验证后按钮倒计时功能(防止刷新倒计时失效)
2017/07/07 Javascript
JavaScript编程设计模式之构造器模式实例分析
2017/10/25 Javascript
详解在React.js中使用PureComponent的重要性和使用方式
2018/07/10 Javascript
JavaScript设计模式之原型模式分析【ES5与ES6】
2018/07/26 Javascript
小程序tab页无法传递参数的方法
2018/08/03 Javascript
浅谈Vuex注入Vue生命周期的过程
2019/05/20 Javascript
微信小程序实现批量倒计时功能
2020/11/01 Javascript
[36:20]完美世界DOTA2联赛PWL S3 access vs Rebirth 第一场 12.17
2020/12/18 DOTA
flask使用session保存登录状态及拦截未登录请求代码
2018/01/19 Python
Python使用正则表达式获取网页中所需要的信息
2018/01/29 Python
使用python读取txt文件的内容,并删除重复的行数方法
2018/04/18 Python
Python处理菜单消息操作示例【基于win32ui模块】
2018/05/09 Python
Python SVM(支持向量机)实现方法完整示例
2018/06/19 Python
Django 大文件下载实现过程解析
2019/08/01 Python
python 爬取B站原视频的实例代码
2020/09/09 Python
Python爬虫+tkinter界面实现历史天气查询的思路详解
2021/02/22 Python
用html5的canvas和JavaScript创建一个绘图程序的简单实例
2016/07/06 HTML / CSS
美国开幕式潮店:Opening Ceremony
2018/02/10 全球购物
shell程序如何生命变量?shell变量是弱变量吗?
2014/11/10 面试题
建筑毕业生自我鉴定
2013/10/18 职场文书
运动会入场式解说词
2014/02/18 职场文书
2015年大学班级工作总结
2015/04/28 职场文书
工作态度检讨书范文
2015/05/06 职场文书
2016年社区创先争优活动总结
2016/04/05 职场文书
go设置多个GOPATH的方式
2021/05/05 Golang
Python实现生成bmp图像的方法
2021/06/13 Python
golang使用map实现去除重复数组
2022/04/14 Golang