洗礼灵魂,修炼python(42)--巩固篇—type内置函数与类的千丝万缕关系
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内置函数与类的千丝万缕关系的更多相关文章
- Python学习(八) —— 内置函数和匿名函数
一.递归函数 定义:在一个函数里调用这个函数本身 递归的最大深度:997 def func(n): print(n) n += 1 func(n) func(1) 测试递归最大深度 import sy ...
- python基础12_匿名_内置函数
一个二分查找的示例: # 二分查找 示例 data = [1, 3, 6, 7, 9, 12, 14, 16, 17, 18, 20, 21, 22, 23, 30, 32, 33, 35, 36, ...
- 【python】dir(__builtins__)查看python中所用BIF(内置函数)
dir(__builtins__)查看python中所用BIF(内置函数)
- 查看python内部模块命令,内置函数,查看python已经安装的模块命令
查看python内部模块命令,内置函数,查看python已经安装的模块命令 可以用dir(modules) 或者用 pip list或者用 help('modules') 或者用 python -m ...
- Python基础(十一)--内置函数
内置函数 数学类 abs():绝对值 round():四舍五入 >>> round(1.3747,1) 1.4 sum():求和 >>> sum({1:'dj',2 ...
- Python开发【第五篇】内置函数
abs() 函数返回数字的绝对值 __author__ = "Tang" a = -30 all() 函数用于判断给定的可迭代参数iterable中的所有元素是否都为True,如果 ...
- python 基础篇 15 内置函数和匿名函数
------------------------>>>>>>>>>>>>>>>内置函数<<< ...
- python学习之路-4 内置函数和装饰器
本篇涉及内容 内置函数 装饰器 内置函数 callable() 判断对象是否可以被调用,返回一个布尔值 1 2 3 4 5 6 7 8 9 10 11 num = 10 print(callabl ...
- python全栈开发-Day13 内置函数
一.内置函数 注意:内置函数id()可以返回一个对象的身份,返回值为整数. 这个整数通常对应与该对象在内存中的位置,但这与python的具体实现有关,不应该作为对身份的定义,即不够精准,最精准的还是以 ...
随机推荐
- Python函数学习——作用域与嵌套函数
全局与局部变量 在函数中定义的变量称为局部变量,在程序的一开始定义的变量称为全局变量. 全局变量作用域是整个程序,局部变量作用域是定义该变量的函数. 当全局变量与局部变量同名时,在定义局部变量的函数内 ...
- 解决Eclipse中DDMS一直打印输出Connection attempts的问题
Eclipse/MyEclipse出现以下错误的解决方案: [2015-01-25 16:10:29 - DeviceMonitor] Adb connection Error:远程主机强迫关闭了一个 ...
- 非table结构数据导入excel
现在大部分的数据都是ul li 展示,一下提供方法 <!DOCTYPE html><html> <head> <meta charset="UTF- ...
- BitMap位图与海量数据的理解与应用
1. Bit Map算法简介 来自于<编程珠玑>.所谓的Bit-map就是用一个bit位来标记某个元素对应的Value, 而Key即是该元素.由于采用了Bit为单位来存储数据,因此在存储空 ...
- mybatis中动态SQL之trim详解
一. 背景 之前mybatis中<where>.<update>.<if>.<foreach>标签用的多,知道有<trim>这个标签,但很少 ...
- Linux 安装 JDK
本篇博客用于记录一下在 Linux 系统下安装 Java 环境. 在大部分的 Linux 系统中都有安装 Open JDK,所以最好是先卸载 Open JDK 后在进行我们的 JDK 安装.Open ...
- Spring的第三天AOP之xml版
Spring的第三天AOP之xml版 ssm框架 spring AOP介绍 AOP(Aspect Oriented Programming),面向切面编程.它出来的目的并不是去取代oop,而是对它的 ...
- SpringBoot之使用Scheduled做定时任务
定时任务有好多开源框架比如Quartz,@Scheduled是Spring的一个定时任务注解,通过注解配置就能够轻量级的定时任务,简单方便. 一.@Scheduled注解介绍 这里先贴上@Schedu ...
- 《深入理解Java虚拟机》(四)虚拟机性能监控与故障处理工具
虚拟机性能监控与故障处理工具 详解 4.1 概述 本文参考的是周志明的 <深入理解Java虚拟机> 第四章 ,为了整理思路,简单记录一下,方便后期查阅. JDK本身提供了很多方便的JVM性 ...
- asp.net mvc5轻松实现插件式开发
在研究Nopcommece项目代码的时候,发现Nop.Admin是作为独立项目开发的,但是部署的时候却是合在一起的,感觉挺好 这里把他这个部分单独抽离出来, 主要关键点: 确保你的项目是MVC5 而不 ...