type函数的隐藏属性

相信大家都知道内置函数type是用来查看对象的数据类型的。例:

那比如我对int类查看类型呢?

有朋友会说,int是内置类啊,用自定义的应该不会这样,我们自定义一个类呢?

还是【type】,那如果使用python2,不继承object类呢?

哎,果然,不继承object类就没事了,但它是还是一个类对象(classobj)啊,换句话说它还是一个对象啊,那我们用isinstance看看test是不是对象呢?

返回True,果然是啊,那再看看基类object呢?

还是这个【type】,还是逃不了

那这个【type】又是什么呢?

结果是它自身

那么这【type】到底是什么?type类,有吗?不急着说,先说说type另一个功能,这个功能却没多少人知道,在 Stack overflow有一位大神e-satis说,它还能创建类,是不是想说,卧槽,这么吊?确实可以的

先看看type函数到底有哪些用法:

其中有个用法:

type(类名, 父类的元组(针对继承的情况,可以为空),包含属性的字典(名称和值))

那么这个怎么用呢?

试试看:

试试用class关键词定义一样否呢?

好像一样的,对吧?不急着下结论,传入属性看看:

哎呀,一样的,继承一个类呢?

确实一样的。要注意的是,使用type时第二个参数是继承对象,因为参数必须是个元组,当只有一个元素时,得加入逗号才能表示是一个元组(这个在前面元组篇说过的)

那么这是什么原理呢?

首先,我们在之前就掌握的知识点——类也是对象,你可以动态的创建类,可以给类进行重新赋值,复制,添加属性,添加方法等操作,当使用class关键字创建类时,在python内部是怎么操作的?这就是通过元类来实现的。

元类(metaclass)是什么

元类就是用来创建类的“工具”,当创建类目的就是为了创建类的实例对象对吧?需要实例化类对象才能进行我们想要的操作,实现我们希望实现的功能对吧?创建好类后,能够通过类创建出实例化的对象,而类本身也是一个实例对象,不过它是元类的实例对象。而我们已经知道类也是对象。那么,你有没有想过,类这个对象又是被谁创建的呢?我们用class关键词创建时,python是怎么识别并创建类对象的呢?

从表层上说,这是python的解释器自动创建的这个类,从深层上说,这是元类“搞的鬼”,元类就是用来创建这些类(对象)的,元类就是类的类,你可以这样理解

元类和type有什么关系?

在刚才的例子里:

type实际上是一个元类metaclass)。type就是Python在背后用来创建所有类的元类。可以类比一下,int是用来创建整数对象的类,list是用来创建列表对象的类,str是用来创建字符串的类等等的,而这些int类,list类,dict类等等全部都是对象,全部都从一个类创建而来——type:

比如博文的最开始a=3这个例子:

所以,元类就是创建类这种对象的工具或者东西,type就是Python的内建元类

当然你可以创建自己的元类(如果你想的话)

自定义元类

1.__metaclass__属性

要想创建自己的元类,就得使用__metaclass__属性

当使用class Test()创建类时,此时Test还不存在于内存中,当使用了__meaclass__就会用元类来创建类Test,这时python会在类的定义中寻找__metaclass__属性,如果有这个属性,就会创建。如果没有就会用内建的type来创建这个类对象。

当然,如果使用继承也是一样的,比如:

使用继承的话,python会判断Test是否有__metaclass__属性,如果有就通过__metaclass__创建,如果没有又从继承的父类Parent类里找有没有__metaclass__,如果有就通过__metaclass__创建,如果还是没有则查找当前主程序模块(__main__,是的,就是 【if __name__ == '__main__'】里的__main__)查找是否有__metaclass__属性,同样的,有就通过其创建,没有就用内置的type创建这个类对象

 这里我个人的理解是:在创建类时,python会判断是否有__metaclass__属性,如果有则按照__metaclass__的特性来创建,如果没有则直接用type来创建一个普通的类,比如一个list,int,str类。

那么我们可以在__metaclass__属性里放置什么呢?可以放置一个type来创建类对象的工具(也可以是type的子类)

2.元类定义的目的

元类的主要目的就是为了当创建类时能够自动地改变类。通常的用途在于可以在web框架或者API做这样的事情,只要是希望可以创建符合当前上下文的类

自己去体会django里的用法,你会发现,格式是创建的类的格式,但是效果和每行代码的意思完全和常识的类无关了。

元类本身而言,它们其实是很简单的:

  • 拦截类的创建(到底用__metaclass__还是用type来创建)
  • 修改类(__meta__=type……)
  • 返回修改之后的类

3.使用元类的原因

“元类就是深度的魔法,99%的用户应该根本不必为此操心。如果你想搞清楚究竟是否需要用到元类,那么你就不需要它。那些实际用到元类的人都非常清楚地知道他们需要做什么,而且根本不需要解释为什么要用元类。”  —— Python界的领袖 Tim Peters

换句话就是,当我们在想搞清楚什么时候需要用到元类时,那么你就不需要用它了,要用它都是非常清楚它能干什么的。知道这个就行,如果没有接触到深层次的开发,不用管它。并且,元类是很复杂的。对于非常简单的类,没必要通过使用元类来对类做修改

洗礼灵魂,修炼python(42)--巩固篇—type内置函数与类的千丝万缕关系的更多相关文章

  1. Python学习(八) —— 内置函数和匿名函数

    一.递归函数 定义:在一个函数里调用这个函数本身 递归的最大深度:997 def func(n): print(n) n += 1 func(n) func(1) 测试递归最大深度 import sy ...

  2. python基础12_匿名_内置函数

    一个二分查找的示例: # 二分查找 示例 data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35, 36, ...

  3. 【python】dir(__builtins__)查看python中所用BIF(内置函数)

    dir(__builtins__)查看python中所用BIF(内置函数)

  4. 查看python内部模块命令,内置函数,查看python已经安装的模块命令

    查看python内部模块命令,内置函数,查看python已经安装的模块命令 可以用dir(modules) 或者用 pip list或者用 help('modules') 或者用 python -m  ...

  5. Python基础(十一)--内置函数

    内置函数 数学类 abs():绝对值 round():四舍五入 >>> round(1.3747,1) 1.4 sum():求和 >>> sum({1:'dj',2 ...

  6. Python开发【第五篇】内置函数

    abs() 函数返回数字的绝对值 __author__ = "Tang" a = -30 all() 函数用于判断给定的可迭代参数iterable中的所有元素是否都为True,如果 ...

  7. python 基础篇 15 内置函数和匿名函数

    ------------------------>>>>>>>>>>>>>>>内置函数<<< ...

  8. python学习之路-4 内置函数和装饰器

    本篇涉及内容 内置函数 装饰器 内置函数 callable()   判断对象是否可以被调用,返回一个布尔值 1 2 3 4 5 6 7 8 9 10 11 num = 10 print(callabl ...

  9. python全栈开发-Day13 内置函数

    一.内置函数 注意:内置函数id()可以返回一个对象的身份,返回值为整数. 这个整数通常对应与该对象在内存中的位置,但这与python的具体实现有关,不应该作为对身份的定义,即不够精准,最精准的还是以 ...

随机推荐

  1. Python函数学习——作用域与嵌套函数

    全局与局部变量 在函数中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量. 全局变量作用域是整个程序,局部变量作用域是定义该变量的函数. 当全局变量与局部变量同名时,在定义局部变量的函数内 ...

  2. 解决Eclipse中DDMS一直打印输出Connection attempts的问题

    Eclipse/MyEclipse出现以下错误的解决方案: [2015-01-25 16:10:29 - DeviceMonitor] Adb connection Error:远程主机强迫关闭了一个 ...

  3. 非table结构数据导入excel

    现在大部分的数据都是ul li 展示,一下提供方法 <!DOCTYPE html><html> <head> <meta charset="UTF- ...

  4. BitMap位图与海量数据的理解与应用

    1. Bit Map算法简介 来自于<编程珠玑>.所谓的Bit-map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素.由于采用了Bit为单位来存储数据,因此在存储空 ...

  5. mybatis中动态SQL之trim详解

    一. 背景 之前mybatis中<where>.<update>.<if>.<foreach>标签用的多,知道有<trim>这个标签,但很少 ...

  6. Linux 安装 JDK

    本篇博客用于记录一下在 Linux 系统下安装 Java 环境. 在大部分的 Linux 系统中都有安装 Open JDK,所以最好是先卸载 Open JDK 后在进行我们的 JDK 安装.Open ...

  7. Spring的第三天AOP之xml版

    Spring的第三天AOP之xml版 ssm框架 spring  AOP介绍 AOP(Aspect Oriented Programming),面向切面编程.它出来的目的并不是去取代oop,而是对它的 ...

  8. SpringBoot之使用Scheduled做定时任务

    定时任务有好多开源框架比如Quartz,@Scheduled是Spring的一个定时任务注解,通过注解配置就能够轻量级的定时任务,简单方便. 一.@Scheduled注解介绍 这里先贴上@Schedu ...

  9. 《深入理解Java虚拟机》(四)虚拟机性能监控与故障处理工具

    虚拟机性能监控与故障处理工具 详解 4.1 概述 本文参考的是周志明的 <深入理解Java虚拟机> 第四章 ,为了整理思路,简单记录一下,方便后期查阅. JDK本身提供了很多方便的JVM性 ...

  10. asp.net mvc5轻松实现插件式开发

    在研究Nopcommece项目代码的时候,发现Nop.Admin是作为独立项目开发的,但是部署的时候却是合在一起的,感觉挺好 这里把他这个部分单独抽离出来, 主要关键点: 确保你的项目是MVC5 而不 ...