Python 面向对象高阶-----metaclass

前言

类也是对象,既然类是对象,那就自然是某个东西的实例化,这个东西就是type

首先看下type是怎么回事

type

type最常用的方法就是查看类型,这只是他的基础用法罢了

>>> print(type(1))
<type 'int'>
>>> print(type(""))
<type 'str'>
>>> print(type(ObjectCreator))
<type 'type'>
>>> print(type(ObjectCreator()))
<class '__main__.ObjectCreator'>

type 通过传入其他参数也可以实现类的创建

普通方式创建类:

class Foo(object):
bar = True def echo_bar(self):
print(self.bar)

继承关系的方式

class FooChild(Foo):
pass

type 方式创建类:

def echo_bar(self):
print(self.bar) Foo = type('Foo', (), {'bar':True, 'echo_bar': echo_bar})

 有继承关系方式

FooChild = type('FooChild', (Foo, ), {})

以上两种方法是等效的

type 的类创建方式的参数需要三个:

  • 类的名字
  • 一组"类的父类"的元组(tuple) (这个会实现继承,也可以为空)
  • 字典 (类的属性名与值,key-value的形式,不传相当于为空,如一般写法中的pass).

metaclass

说白了,函数 type 就是一个特殊的metaclass.
python在背后使用 type 创造了所有的类。type是所有类的metaclass.

在python中,一切皆为对象:整数、字符串、函数、类.所有这些对象,都是通过类来创造的.

    >>> age = 35
>>> age.__class__
<type 'int'> >>> name = 'bob'
>>> name.__class__
<type 'str'> >>> def foo(): pass
>>> foo.__class__
<type 'function'> >>> class Bar(object): pass
>>> b = Bar()
>>> b.__class__
<class '__main__.Bar'>

而__class____class__则就是由 type 来的了

    >>> age.__class__.__class__
<type 'type'>
>>> name.__class__.__class__
<type 'type'>
>>> foo.__class__.__class__
<type 'type'>
>>> b.__class__.__class__
<type 'type'>

metaclass就是创造类对象的工具.如果你喜欢,你也可以称之为"类的工厂".

type是python內置的metaclass。不过,你也可以编写自己的metaclass.

指定 metaclass

class Foo(metaclass=MyType):    # python 3
  # __metaclass__ = MyType    # python 2
  pass

流程

Foo中有__metaclass__这个属性吗?

有:

  如果有,会在内存中通过__metaclass__创建一个名字为Foo的类对象。

没有:

  如果没有__metaclass__,它会继续在Bar(父类)中寻找,并尝试做和前面同样的操作。

  如果父类也没有找到__metaclass__,它就会在模块(module)中去寻找__metaclass__,并尝试做同样的操作。

  如果始终都找不到__metaclass__, 最终只能使用内置的type(这也是一个metaclass)来创建这个类对象。

自定义metaclass

使用metaclass的主要目的,是为了能够在创建类的时候,自动地修改类

自定义 metaclass 首先就需要自定义一个不同于 type 的自定义 MyType,能够实现之前的 type 的类创建功能基础上在实现其他想要的功能

class MyType(type):
def __init__(self,*args,**kwargs):
super().__init__(*args,**kwargs) def __call__(cls, *args, **kwargs):
obj = cls.__new__(cls) cls.__init__(obj,*args, **kwargs) return obj

在创建类的时候指定 metaclass 为 自定义的 MyType 即可

class Foo(object,metaclass=MyType):  # metaclass 指定由谁来创建这个类
a1 = 123
def __init__(self):
pass def __new__(cls, *args, **kwargs):
return object.__new__(cls) def func(self):
return 666

那么在此类创建实例的时候的流程是怎样的呢?

foo = Foo()

流程

创建类时

先执行 MyType 的 __init__ 方法 ,由super 转向先执行 父类 type 的 __init__ 来创建类

类实例化时

当一个类在实例化时候,先执行 type 的 __call__ 方法 , __call__ 方法 的返回值就是实例化对象

__call__ 内部调用:

  类.__new__ 方法 :创建对象

  类.__init__ 方法 :对象初始化

Python 面向对象高阶-----metaclass的更多相关文章

  1. day37-1 面向对象高阶

    目录 面向对象高阶 isinstance issubclass 反射(自省) 模块的使用 放在类的使用 call 面向对象高阶 isinstance 判断是否为实例化对象,以后可以用来取代type 和 ...

  2. python基础——高阶函数

    python基础——高阶函数 高阶函数英文叫Higher-order function.什么是高阶函数?我们以实际代码为例子,一步一步深入概念. 变量可以指向函数 以Python内置的求绝对值的函数a ...

  3. Python的高阶函数小结

    一. 高阶函数定义 简而言之,Python的高阶函数就是指一个函数作为参数传递给另外一个函数的用法. 举一个最简单的高阶函数来说明: >>> def add(x,y,f): retu ...

  4. python 验证码 高阶验证

    python 验证码 高阶验证 标签: 验证码python 2016-08-19 15:07 1267人阅读 评论(1) 收藏 举报  分类: 其他(33)    目录(?)[+]   字符型图片验证 ...

  5. python之高阶函数编程

    在这篇文章中我指出两点: 第一:系统函数可以被覆盖 比如: a=abs(-10) print a 10 但是,如果把函数本身赋值给变量呢? f = abs f <built-in functio ...

  6. Python笔记-高阶函数

    1.函数式编程 函数式编程就是一种抽象程度很高的编程范式,纯粹的函数式编程语言编写的函数没有变量. 函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数! 传入函数 既然 ...

  7. python的高阶函数式编程

    首先   函数式编程≠函数编程,就跟计算机≠计算,因为计算机基于硬件,计算基于算法,所以函数式编程是倾向于算法. 高阶函数定义: 一个函数接受的这个参数,而这个参数也是一个函数,称之为高阶函数 例如: ...

  8. Python练习-高阶函数-2018.12.03

    1.函数式编程的概念 在计算机的层次上,CPU执行的是加减乘除的指令代码,以及各种条件判断和跳转指令,所以,汇编语言是最贴近计算机的语言. 而计算则指数学意义上的计算,越是抽象的计算,离计算机硬件越远 ...

  9. Python 基础 高阶函数

    python 把函数作为参数 如果传入abs 作为参数 def add(x,y,y): return f(x) + f(y) add(-5,9,abs) 根据函数的定义,函数执行的代码实际上是. ab ...

随机推荐

  1. android如何获取SHA1

    某些Google Play服务(例如Google登录和App Invites)要求我们提供签名证书的SHA-1,以便google paly为我们的应用创建OAuth2客户端和API密钥. 那么如何获取 ...

  2. 坚定关于考研或者工作的决定:work

    转眼之间,我已经夸过了大二结束的节点,已经是一个准大三了: 在这个岔路口,首要的选择就是考研和工作的选择:我也有过犹豫要不要考研,最终还是放弃了考研的想法,从考研的利弊两个方面来谈:        首 ...

  3. ext遍历表单中所有输入项,并全部设置为只读

    baseInfoForm.getForm().getFields().each(function (field) { // 设置只读 field.setReadOnly(true); })

  4. win10 系统 wifi自动断开连接 wifi热点不稳定

    我的系统的电脑是win10系统,笔记本 下载了一个wifi共享大师,但是wifi总是自动断,于是就找了找问题所在 在网上看了许多方案,大多数都是    在   电源管理  把[允许计算机关闭此设备以节 ...

  5. Ubuntu忘记密码后强制修改密码

    环境:Ubuntu 16.04 由于很久不用我的Ubuntu系统导致密码忘记,就想着应该有什么办法可以强制修改root密码,就上百度找了一下,果然Ubuntu有办法强制修改root密码. 在这里要谢谢 ...

  6. windows拿到cmd权限之后常用命令

    whoami    // 查看当前用户名称 ipconfig    // 查看本机ip信息,可加 /all 参数 netstat -ano // 查看端口清况 dir c:\  // 查看目录 typ ...

  7. Vmware10中Centos7挂载Windows主机的共享文件夹,提示:Error: cannot mount filesystem: No such device

    1.设置共享权限 2.安装VMware tools 点击虚拟机 点击安装 VMware tools 将/run/media/zhaojq/VMware\ Tools 目录下的VMwareTools-9 ...

  8. LeetCode练习4 找出这两个有序数组的中位数

    给定两个大小为 m 和 n 的有序数组 nums1 和 nums2. 请你找出这两个有序数组的中位数,并且要求算法的时间复杂度为 O(log(m + n)). 你可以假设 nums1 和 nums2  ...

  9. WebApi的自定义Filter

    using System; using System.Collections.Generic; using System.Linq; using System.Net.Http; using Syst ...

  10. map和unordered_map的差别和使用

    map和unordered_map的差别还不知道或者搞不清unordered_map和map是什么的,请见:http://blog.csdn.net/billcyj/article/details/7 ...