元类(MetaClasses)

元类提供了一个改变Python类行为的有效方式。

元类的定义是“一个类的类”。任何实例是它自己的类都是元类。

class demo(object):
pass obj = demo() print "Class of obj is {0}".format(obj.__class__)
print "Class of obj is {0}".format(demo.__class__) # Class of obj is <class '__main__.demo'>
# Class of obj is <type 'type'>

在上例中,我们定义了一个类demo,并且生成了一个该类的对象obj。首先,可以看到obj的__class__是demo。有意思的来了,那么demo的class又是什么呢?可以看到demo的__class__是type。

所以说type是python类的类,换句话说,上例中的obj是一个demo的对象,而demo本身又是type的一个对象。

所以说type就是一个元类,而且是python中最常见的元类,因为它使python中所有类的默认元类。

因为元类是类的类,所以它被用来创建类(正如类是被用来创建对象的一样)。但是,难道我们不是通过一个标准的类定义来创建类的么?的确是这样,但是python内部的运作机制如下:

    • 当看见一个类定义,python会收集所有属性到一个字典中。
    • 当类定义结束,python将决定类的元类,我们就称它为Meta吧。
    • 最后,python执行Meta(name, bases, dct),其中:

a. Meta是元类,所以这个调用是实例化它。
b. name是新建类的类名。
c. bases是新建类的基类元组
d. dct将属性名映射到对象,列出所有的类属性。

那么如何确定一个类(A)的元类呢?简单来说,如果一个类(A)自身或其基类(Base_A)之一有__metaclass__属性存在,则这个类(A/Base_A)就是类(A)的元类。否则type就将是类(A)的元类。

metaclass 原理

metaclass的原理其实是这样的:当定义好类之后,创建类的时候其实是调用了type的__new__方法为这个类分配内存空间,创建

好了之后再调用type的__init__方法初始化(做一些赋值等)。所以metaclass的所有magic其实就在于这个__new__方法里面了。

说说这个方法:__new__(cls, name, bases, attrs)

cls: 将要创建的类,类似与self,但是self指向的是instance,而这里cls指向的是class

name: 类的名字,也就是我们通常用类名.__name__获取的。

bases: 基类

attrs: 属性的dict。dict的内容可以是变量(类属性),也可以是函数(类方法)。

所以在创建类的过程,我们可以在这个函数里面修改name,bases,attrs的值来自由的达到我们的功能。这里常用的配合方法是

getattr和setattr(just an advice)

廖雪峰Python学习笔记——使用元类的更多相关文章

  1. 廖雪峰Python学习笔记——类和实例

    Class MyList(list): __metaclass__ = ListMetaclass #它表示在创建MyList这个类时,必须通过 ListMetaclass这个元类的LIstMetac ...

  2. 廖雪峰Python学习笔记——序列化

    序列化 定义:程序运行时所有变量都存在内存中,把变量从内存中变成可存储或可传输的过程称为序列化pickling,在其他语言中称为serialization,marshalling,flattening ...

  3. python 学习笔记7(类/对象的属性;特性,__getattr__)

    27. 属性的__dict__系统 1)对象的属性可能来自: 其类的定义,叫做类属性 继承父类的定义 该对象实例定义(初始化对象时赋值),叫做对象属性 2)对象的属性存储在对象的 __dict__ 属 ...

  4. Python学习笔记:05类

    类 Python是面向对象的语言,面向对象最重要的三个优点有: 多态:多态使对象具备不同的行为方式.(可以认为声明了接口,但是实现方式可能多样) 封装:封装是对全局作用域中隐藏多余信息的原则(创建对象 ...

  5. Python学习笔记总结(三)类

    一.类简单介绍 1.介绍 类是Python面向对象程序设计(OOP)的主要工具,类建立使用class语句,通过class定义的对象. 类和模块的差异,类是语句,模块是文件. 类和实例 实例:代表程序领 ...

  6. python学习笔记(六)、类

    Python与java.c++等都被视为一种面向对象的语言.通过创建自定义类,用于处理各种业务逻辑.面向对象有封装.继承.多态三个特征,这也是面子对象语言的通用特征. 1 封装 封装,是值向外部隐藏内 ...

  7. python学习笔记9-单元测试unittest

    Python中有一个自带的单元测试框架是unittest模块,用它来做单元测试,它里面封装好了一些校验返回的结果方法和一些用例执行前的初始化操作. 在说unittest之前,先说几个概念: TestC ...

  8. Python学习笔记8-单元测试(1)

    源代码: roman_mumeral_map = (('M',1000), ('CM',900), ('D',500), ('CD',400), ('C',100), ('XC',90), ('L', ...

  9. python学习笔记六--用户自定义类

    一.类: 1. 面向对象. 2. 定义了新的对象类型. 定义了两个属性:name,pay 定义了两个方法:lastName,giveRaise

随机推荐

  1. myschool 相思树

    题目描述 一群妖王排成一排站在苦情巨树下,寻找自己的转世恋人.虽然都是妖王,但按照涂山的规定必须进行标号,标号为1的妖王排在最后面,标号为n的妖王排在最前面.每个妖王只有一个妖力值a[i]表示它们现在 ...

  2. 三维dem

    关注World wind Java,<World wind Java三维地理信息系统开发指南随书光盘 1. 下载worldwind java sdk 下载地址:http://builds.wor ...

  3. 老板说你的UI设计的不高级?你肯定没用这7个技巧...

    对于每个网页设计师而言,在设计过程中总会碰到需要作出设计决策的时候.也许你的公司并没有全职设计师,而需求上则要求设计出全新的UI:又或者你正在制作一个你自己的个人项目,而你希望它比 Bootstrap ...

  4. array_column()提取二维数组中某个值

    <?php $multipleCommodity = array( =>array(), =>array() ); $arr1=array_column($multipleCommo ...

  5. 使用phpExcel导出excel文件

    function export($log_list_export) { require "../include/phpexcel/PHPExcel.php"; require &q ...

  6. 在cygwin中执行bat文件

    在cygwin中执行bat文件 #!/bin/bash dir_gen_image_bat=C:/MinGW/msys/1.0/home/Administrator/feitian_audio/FOT ...

  7. jetty无法即时更新html、js、css等静态文件的解决办法

    网上搜了一大堆方法.最常见的是找到jetty\etc\webdefault.xml文件,找到useFileMappedBuffer参数,把true改为false <init-param> ...

  8. 什么是@guid

    我将给大家讲解史上最通俗一同guid与ID的区别...

  9. jquery判断显示的元素并获取显示元素数据

    // 获取显示元素的数据 jQuery(this).find("a:visible").attr("href"); // 多级标签选择器 jQuery(&quo ...

  10. 2018.07.01 洛谷小B的询问(莫队)

    P2709 小B的询问 题目描述 小B有一个序列,包含N个1~K之间的整数.他一共有M个询问,每个询问给定一个区间[L..R],求Sigma(c(i)^2)的值,其中i的值从1到K,其中c(i)表示数 ...